Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

West-Midlands-Community | Matthew Law | Module-Data-Flows | WEEK 12 | Challenges #146

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
41 changes: 24 additions & 17 deletions challenges/challenge-cowsay-two/solution1.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
// =================
// Stripped down cowsayer CLI,
// no libraries
// https://nodejs.dev/learn/nodejs-accept-arguments-from-the-command-line
// Stripped down cowsayer CLI, no libraries
// =================

// 1. Accept arguments

// how will you accept arguments?
// Accept the argument from the command line
const args = process.argv.slice(2); // Skip node and script name
let saying = args[0] || "Moo!"; // Default saying if no argument is provided

// 2. Make supplies for our speech bubble

let topLine = '_';
let bottomLine = '-';
let saying = '';

// 3. Make a cow that takes a string

function cowsay(saying) {
// how will you make the speech bubble contain the text?

// where will the cow picture go?

// how will you account for the parameter being empty?

// Create speech bubble
const speechBubble = `
${topLine.repeat(saying.length + 2)}
< ${saying} >
${bottomLine.repeat(saying.length + 2)}
`;

// Add ASCII cow to speech bubble
const cow = `
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
`;

// Combine speech bubble and cow
return speechBubble + cow;
}

//4. Pipe argument into cowsay function and return a cow

// how will you log this to the console?
// 4. Pipe argument into cowsay function and return a cow
console.log(cowsay(saying));
46 changes: 37 additions & 9 deletions challenges/challenge-cowsay-two/solution2.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
// =================
// Stripped down cowsayer CLI,
// no libraries or arguments
// https://nodejs.dev/learn/accept-input-from-the-command-line-in-nodejs
// Stripped down cowsayer CLI, no libraries or arguments
// =================

// 1. Make a command line interface.
// 1. Make a command line interface.
const readline = require('readline');

// Create readline interface
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

// 2. Make supplies for our speech bubble
let topLine = '_';
let bottomLine = '-';

// 3. Make a cow that takes a string

const cow = (saying) => {
// how did you make the cow before?
}
// Create speech bubble
const speechBubble = `
${topLine.repeat(saying.length + 2)}
< ${saying} >
${bottomLine.repeat(saying.length + 2)}
`;

// Add ASCII cow to speech bubble
const cowArt = `
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
`;

return speechBubble + cowArt;
};

// 4. Use readline to get a string from the terminal
// (with a prompt so it's clearer what we want)
// 4. Use readline to get a string from the terminal
// Prompt the user for input
rl.question("What do you want the cow to say? ", (input) => {
// If input is empty, provide a default message
const saying = input.trim() || "Moo!";
console.log(cow(saying)); // Generate and print the cow with speech bubble
rl.close(); // Close the readline interface
});
19 changes: 19 additions & 0 deletions challenges/dog-photo-gallery/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Random Dog Photo Gallery</title>
<link rel="stylesheet" href="styles.css">
</head>

<body>
<h1>Random Dog Photo Gallery</h1>
<button id="addImageBtn">Add Dog Image</button>
<button id="clearGalleryBtn">Clear Gallery</button>
<ul id="gallery"></ul>

<script src="script.js"></script>
</body>

</html>
32 changes: 32 additions & 0 deletions challenges/dog-photo-gallery/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
document.addEventListener('DOMContentLoaded', () => {
const addImageBtn = document.getElementById('addImageBtn');
const clearGalleryBtn = document.getElementById('clearGalleryBtn');
const gallery = document.getElementById('gallery');

addImageBtn.addEventListener('click', fetchAndDisplayImage);
clearGalleryBtn.addEventListener('click', () => {
gallery.innerHTML = '';
});

async function fetchAndDisplayImage() {
try {
const response = await fetch('https://dog.ceo/api/breeds/image/random');
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
if (data.status !== 'success') {
throw new Error('Failed to fetch dog image.');
}
const listItem = document.createElement('li');
const image = document.createElement('img');
image.src = data.message;
image.alt = 'Random Dog';
listItem.appendChild(image);
gallery.appendChild(listItem);
} catch (error) {
console.error('Error fetching and displaying image:', error);
alert('Failed to load dog image. Please try again later.');
}
}
});
62 changes: 62 additions & 0 deletions challenges/dog-photo-gallery/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}

#gallery {
list-style-type: none;
padding: 0;
}

#gallery li {
display: inline-block;
margin: 10px;
}

#gallery img {
max-width: 200px;
border-radius: 8px;
}

#addImageBtn {
padding: 10px 20px;
margin: 10px;
border: none;
background-color: #007BFF;
color: white;
font-size: 16px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
}

#addImageBtn:hover {
background-color: #0056b3;
transform: scale(1.05);
}

#addImageBtn:focus {
outline: 2px solid #003f7f;
}

#clearGalleryBtn {
padding: 10px 20px;
margin: 10px;
border: none;
background-color: #FF5733;
color: white;
font-size: 16px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
}

#clearGalleryBtn:hover {
background-color: #c44123;
transform: scale(1.05);
}

#clearGalleryBtn:focus {
outline: 2px solid #922d17;
}
21 changes: 21 additions & 0 deletions challenges/unit-testing/katas-tdd/calculator/stringCalculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function add(numbers) {
// Step 1: Handle an empty string
if (numbers === "") return 0;

// Step 2: Handle an unknown number of inputs
const numArray = numbers.split(",").map(Number);

// Step 3: Ignore numbers greater than 1000
const filteredNumbers = numArray.filter(num => num <= 1000);

// Step 4: Handle negative numbers
const negatives = filteredNumbers.filter(num => num < 0);
if (negatives.length > 0) {
throw new Error(`negatives not allowed: ${negatives.join(", ")}`);
}

// Sum up the valid numbers
return filteredNumbers.reduce((sum, num) => sum + num, 0);
}

module.exports = add;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const add = require("./stringCalculator");

describe("String Calculator", () => {
// Step 1: Simplest case
test("should return 0 for an empty string", () => {
expect(add("")).toBe(0);
});

test("should return the number itself for a single number", () => {
expect(add("5")).toBe(5);
});

test("should return the sum of two numbers", () => {
expect(add("3,6")).toBe(9);
});

// Step 2: Handle an unknown amount of numbers
test("should handle an unknown amount of numbers", () => {
expect(add("1,2,3,4,5")).toBe(15);
});

// Step 3: Ignore big numbers
test("should ignore numbers greater than 1000", () => {
expect(add("2,1001")).toBe(2);
expect(add("1000,1001")).toBe(1000);
});

// Step 4: Negative numbers
test("should throw an error for a single negative number", () => {
expect(() => add("-1")).toThrow("negatives not allowed: -1");
});

test("should throw an error for multiple negative numbers", () => {
expect(() => add("1,-4,-1")).toThrow("negatives not allowed: -4, -1");
});
});
21 changes: 21 additions & 0 deletions challenges/unit-testing/katas-tdd/password-verifier/verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Step 1: Check for null or too short passwords
function verify(password) {
if (!password || password.length < 8) {
return "Password rejected";
}

// Step 2: Check for at least one uppercase letter
if (!/[A-Z]/.test(password)) {
return "Password rejected";
}

// Step 3: Check for at least one numeric character
if (!/[0-9]/.test(password)) {
return "Password rejected";
}

// Step 4: If all conditions pass
return "Password accepted";
}

module.exports = verify;
34 changes: 34 additions & 0 deletions challenges/unit-testing/katas-tdd/password-verifier/verify.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const verify = require('./verify');

describe("Password Verifier", () => {

// Step 1: Test password length
test("rejects passwords shorter than 8 characters", () => {
expect(verify("short")).toBe("Password rejected");
});

// Step 2: Test null passwords
test("rejects null passwords", () => {
expect(verify(null)).toBe("Password rejected");
});

// Step 3: Test passwords without uppercase letters
test("rejects passwords without uppercase letters", () => {
expect(verify("lowercase1")).toBe("Password rejected");
});

// Step 3: Test passwords with uppercase letters
test("accepts passwords with uppercase letters and at least 8 characters", () => {
expect(verify("ValidPass1")).toBe("Password accepted");
});

// Step 4: Test passwords without numbers
test("rejects passwords without numbers", () => {
expect(verify("NoNumbers")).toBe("Password rejected");
});

// Step 4: Test passwords with all conditions met
test("accepts passwords with numbers and all other conditions met", () => {
expect(verify("Password1")).toBe("Password accepted");
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
function convertToNewRoman(n) {}
function convertToNewRoman(n) {
const romanNumerals = [
{ value: 1000, numeral: 'M' },
{ value: 900, numeral: 'CM' },
{ value: 500, numeral: 'D' },
{ value: 400, numeral: 'CD' },
{ value: 100, numeral: 'C' },
{ value: 90, numeral: 'XC' },
{ value: 50, numeral: 'L' },
{ value: 40, numeral: 'XL' },
{ value: 10, numeral: 'X' },
{ value: 9, numeral: 'IX' },
{ value: 5, numeral: 'V' },
{ value: 4, numeral: 'IV' },
{ value: 1, numeral: 'I' }
];

module.exports = convertToNewRoman;
let result = '';
for (const { value, numeral } of romanNumerals) {
while (n >= value) {
result += numeral;
n -= value;
}
}
return result;
}

module.exports = convertToNewRoman;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ let convertToNewRoman = require("./convert-to-new-roman");

test("returns I if passed 1 as an argument", function () {
// Arrange
const input = 1;
const expectedOutput = "I";

// Act
const result = convertToNewRoman(input);

// Assert
});
expect(result).toBe(expectedOutput);
});
Loading