Skip to content

London 11 | Pezhman-Azizi | Structuring-and-testing-data | week3 | sprint 3 #214

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
25 changes: 24 additions & 1 deletion Sprint-3/implement/get-angle-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

// Identify Acute Angles:
// When the angle is less than 90 degrees,
// Then the function should return "Acute angle"
// Then the function should return " angle"

// Identify Obtuse Angles:
// When the angle is greater than 90 degrees and less than 180 degrees,
Expand All @@ -25,3 +25,26 @@
// Identify Reflex Angles:
// When the angle is greater than 180 degrees and less than 360 degrees,
// Then the function should return "Reflex angle"

function getAngleType(angel){
if (angel === 90){
return "Right angle";
}else if (angel < 90){
return "Acute angle";
}else if(angel>90 && angel < 10){
return "Obtuse angle";
}else if(angel === 180){
return "Straight angle";
}else if(angel>180 && angel<360){
return "Reflex angle"
}else{
return "invalid angel";
}
}
// Test cases
console.assert(getAngleType(45) === "Acute angle", "Failed: Expected Acute angle");
console.assert(getAngleType(90) === "Right angle", "Failed: Expected Right angle");
console.assert(getAngleType(135) === "Obtuse angle", "Failed: Expected Obtuse angle");
console.assert(getAngleType(180) === "Straight angle", "Failed: Expected Straight angle");
console.assert(getAngleType(-10) === "Invalid angle", "Failed: Expected Invalid angle");
console.assert(getAngleType(200) === "Invalid angle", "Failed: Expected Invalid angle");
41 changes: 40 additions & 1 deletion Sprint-3/implement/get-card-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

// Acceptance criteria:

// Given a card string in the format "A♠" (representing a card in blackjack - the last character will always be an emoji for a suit, and all characters before will be a number 2-10, or one letter of J, Q, K, A),
// Given a card string in the format "A♠" (representing a card in blackjack - the last character
// will always be an emoji for a suit, and all characters before will be a number 2-10, or one letter of J, Q, K, A),
// When the function getCardValue is called with this card string as input,
// Then it should return the numerical card value

Expand All @@ -29,3 +30,41 @@
// Given a card with an invalid rank (neither a number nor a recognized face card),
// When the function is called with such a card,
// Then it should throw an error indicating "Invalid card rank."
function getCardValue(card) {
const cardRank = card.slice(0, -1); // Extracts the rank (e.g., "K" from "K♠")
const cardSuit = card.slice(-1); // Extracts the suit (e.g., "♠" from "K♠")
const validRanks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
const validSuits = ["♠", "♥", "♦", "♣"];

if (!validRanks.includes(cardRank) || !validSuits.includes(cardSuit)) {
return "Invalid card rank.";
}

switch (cardRank) {
case "A": return 1;
case "2": return 2;
case "3": return 3;
case "4": return 4;
case "5": return 5;
case "6": return 6;
case "7": return 7;
case "8": return 8;
case "9": return 9;
case "10": return 10;
case "J": return 11;
case "Q": return 12;
case "K": return 13;
default: return "Invalid card rank.";
}
}

// Test cases
console.assert(getCardValue("K♠") === 13, "Failed: Expected 13");
console.assert(getCardValue("Q♣") === 12, "Failed: Expected 12");
console.assert(getCardValue("A♦") === 1, "Failed: Expected 1");
console.assert(getCardValue("10♥") === 10, "Failed: Expected 10");
console.assert(getCardValue("0Q♠") === "Invalid card rank.", "Failed: Expected Invalid card rank.");
console.assert(getCardValue("010♠") === "Invalid card rank.", "Failed: Expected Invalid card rank.");
console.assert(getCardValue("02♠") === "Invalid card rank.", "Failed: Expected Invalid card rank.");
console.assert(getCardValue("0x02♠") === "Invalid card rank.", "Failed: Expected Invalid card rank.");
console.assert(getCardValue("2.1♠") === "Invalid card rank.", "Failed: Expected Invalid card rank.");
17 changes: 17 additions & 0 deletions Sprint-3/implement/is-proper-fraction.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,20 @@
// target output: false
// Explanation: The fraction 3/3 is not a proper fraction because the numerator is equal to the denominator. The function should return false.
// These acceptance criteria cover a range of scenarios to ensure that the isProperFraction function handles both proper and improper fractions correctly and handles potential errors such as a zero denominator.

function isProperFraction(numerator, denominator) {
if (denominator === 0) {
throw new Error("Denominator cannot be zero");
}
return Math.abs(numerator) < Math.abs(denominator);
}

// Test cases
console.assert(isProperFraction(2, 3) === true, "2/3 should be a proper fraction");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also test negative values in numerator and/or denominator (for cases when |numerator| < |denominator|).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expanded the test cases to include scenarios where either the numerator, the denominator, or both are negative, ensuring that the function handles these properly.

console.assert(isProperFraction(3, 2) === false, "3/2 should not be a proper fraction");
console.assert(isProperFraction(-2, 3) === true, "-2/3 should be a proper fraction");
console.assert(isProperFraction(2, -3) === true, "2/-3 should be a proper fraction");
console.assert(isProperFraction(-2, -3) === true, "-2/-3 should be a proper fraction");
console.assert(isProperFraction(3, -2) === false, "3/-2 should not be a proper fraction");
console.assert(isProperFraction(-3, 2) === false, "-3/2 should not be a proper fraction");
console.log("All tests passed!");
23 changes: 20 additions & 3 deletions Sprint-3/implement/is-valid-triangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
// It's also true that b + c > a
// It's also true that a + c > b

// In our function isValidTriangle which takes as parameters the lengths of three sides, we need to invalidate any triangle where the sum of any two sides is less than or equal to the length of the third side.
// In our function isValidTriangle which takes as parameters the lengths of three sides,
// we need to invalidate any triangle where the sum of any two sides is less than or equal to the length of the third side.
// and we need to validate any triangle where the sum of any two sides is greater than the length of the third side.

// Acceptance criteria:

// scenario: invalid triangle
// Given the side lengths a, b, and c,
// When the sum of any two side lengths is less than or equal to the length of the third side (i.e., a + b <= c, a + c <= b, b + c <= a),
// Then it should return false because these conditions violate the Triangle Inequality, which states that the sum of the lengths of any two sides of a triangle must be greater than the length of the third side.
// Then it should return false because these conditions violate the Triangle Inequality,
// which states that the sum of the lengths of any two sides of a triangle must be greater than the length of the third side.

// scenario: invalid triangle
// Check for Valid Input:
Expand All @@ -32,4 +34,19 @@
// When the function is called with these values as input,
// Then it should return true because the input forms a valid triangle.

// This specification outlines the behavior of the isValidTriangle function for different input scenarios, ensuring it properly checks for invalid side lengths and whether they form a valid triangle according to the Triangle Inequality Theorem.
// This specification outlines the behavior of the isValidTriangle function for different input scenarios,
// ensuring it properly checks for invalid side lengths and whether they form a valid triangle according to the Triangle Inequality Theorem.

function isValidTriangle(a, b, c) {
// Checks if the sides satisfy the triangle inequality
return a + b > c && b + c > a && a + c > b;
}

// Test cases
console.assert(isValidTriangle(3, 4, 5) === true, "3, 4, 5 should form a valid triangle");
console.assert(isValidTriangle(1, 2, 3) === false, "1, 2, 3 should not form a valid triangle");
console.assert(isValidTriangle(0, 4, 5) === false, "0, 4, 5 should not form a valid triangle");
console.assert(isValidTriangle(-1, 2, 3) === false, "-1, 2, 3 should not form a valid triangle");
console.assert(isValidTriangle(5, 5, 10) === false, "5, 5, 10 should not form a valid triangle");
console.assert(isValidTriangle(7, 10, 5) === true, "7, 10, 5 should form a valid triangle");
console.assert(isValidTriangle(2, 2, 3) === true, "2, 2, 3 should form a valid triangle");
68 changes: 58 additions & 10 deletions Sprint-3/implement/rotate-char.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,77 @@
// Scenario: Rotate Lowercase Letters:
// Given a lowercase letter character and a positive integer shift,
// When the function is called with these inputs,
// Then it should rotate the lowercase letter by shift positions within the lowercase alphabet, wrapping around if necessary, and return the rotated lowercase letter as a string.
console.log(rotateCharacter("a", 3)); // Output: "d"
console.log(rotateCharacter("f", 1)); // Output: "g"
// Then it should rotate the lowercase letter by shift positions within the lowercase alphabet, wrapping around if necessary,
// and return the rotated lowercase letter as a string.
// console.log(rotateCharacter("a", 3)); // Output: "d"
// console.log(rotateCharacter("f", 1)); // Output: "g"

// Scenario: Rotate Uppercase Letters:
// Given an uppercase letter character and a positive integer shift,
// When the function is called with these inputs,
// Then it should rotate the uppercase letter by shift positions within the uppercase alphabet, wrapping around if necessary, and return the rotated uppercase letter as a string.
console.log(rotateCharacter("A", 3)); // Output: "D"
console.log(rotateCharacter("F", 1)); // Output: "G"
// Then it should rotate the uppercase letter by shift positions within the uppercase alphabet,
// wrapping around if necessary, and return the rotated uppercase letter as a string.
// console.log(rotateCharacter("A", 3)); // Output: "D"
// console.log(rotateCharacter("F", 1)); // Output: "G"

// Scenario: Leave Non-Letter Characters Unchanged:
// Given a character that is not a letter (neither uppercase nor lowercase) and any positive or negative shift value,
// When the function is called with these inputs,
// Then it should return the character unchanged.
// This specification outlines the behavior of the rotateCharacter function for different input scenarios, including valid and invalid characters, and defines the expected output or action for each case.
console.log(rotateCharacter("7", 5)); // Output: "7" (unchanged, not a letter)
// This specification outlines the behavior of the rotateCharacter function for different input scenarios,
// including valid and invalid characters, and defines the expected output or action for each case.
// console.log(rotateCharacter("7", 5)); // Output: "7" (unchanged, not a letter)

// Scenario: Shifting a Character with Wraparound
// Given a character char within the lowercase alphabet range (e.g., 'z') or the uppercase alphabet range (e.g., 'Z'),
// And a positive integer shift that causes the character to wrap around the alphabet when rotated (e.g., a shift of 3 for 'z' or 'Z'),
// When the rotateCharacter function is called with char and shift as inputs,
// Then it should correctly rotate the character by shift positions within the alphabet while handling the wraparound,
// And the function should return the rotated character as a string (e.g., 'z' rotated by 3 should become 'c', 'Z' rotated by 3 should become 'C').
console.log(rotateCharacter("z", 1)); // Output: "a" (preserves case, but wraps around)
console.log(rotateCharacter("Y", 2)); // Output: "A" (preserves case, but wraps around)
// console.log(rotateCharacter("z", 1)); // Output: "a" (preserves case, but wraps around)
// console.log(rotateCharacter("Y", 2)); // Output: "A" (preserves case, but wraps around)





// ------------------------------------------------------------ MY APPROACH------------------------------------------------------------------------------------------
// This approach works with ASCII (American Standard Code for Information Interchange) which assigns a unique numeric code for characters, including
// letters, digits and symbols. In this case we are dealing with letters only.
// Lower case letters range from 97 to 122 and uppercase letters range from 65 to 90.

function rotateCharacter(letter, shift) {
const asciiValue = letter.charCodeAt(0); // Gets the ASCII value for the character

shift = shift % 26; // Normalize the shift for large or negative values

if (asciiValue >= 65 && asciiValue <= 90) { // Uppercase letters
let rotatedAscii = asciiValue + shift;
if (rotatedAscii > 90) {
rotatedAscii -= 26; // Wraparound for uppercase
} else if (rotatedAscii < 65) {
rotatedAscii += 26; // Negative wraparound
}
return String.fromCharCode(rotatedAscii);
} else if (asciiValue >= 97 && asciiValue <= 122) { // Lowercase letters
let rotatedAscii = asciiValue + shift;
if (rotatedAscii > 122) {
rotatedAscii -= 26; // Wraparound for lowercase
} else if (rotatedAscii < 97) {
rotatedAscii += 26; // Negative wraparound
}
return String.fromCharCode(rotatedAscii);
} else {
return letter; // Leave non-letter characters unchanged
}
}

// Test cases
console.log(rotateCharacter("z", -1)); // "y"
console.log(rotateCharacter("a", -1)); // "z"
console.log(rotateCharacter("A", 27)); // "B"
console.log(rotateCharacter("Z", 1)); // "A"
console.log(rotateCharacter("1", 5)); // "1" (unchanged)
console.log(rotateCharacter("!", 3)); // "!" (unchanged)
console.log(rotateCharacter(" ", 10)); // " " (unchanged)

30 changes: 30 additions & 0 deletions Sprint-3/revise/implement/count.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// function countChar(str, char){
// let count = 0;
// str.split("").forEach(element => {
// if (element === char){
// count+=1;}
// });
// if (count > 0){
// return `${char} appears ${count} times in ${str}`;
// }else{
// return `no occurrences of the "${char}" were found in the "${str}"`;
// }
// }
// // exports.countChar = {countChar};
// module.exports = { countChar };
function countChar(str, char) {
let count = 0;
str.split("").forEach(element => {
if (element === char) {
count += 1;
}
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the spec wasn't clear enough. Usually a function that "count something" would simply return an integer.
I am afraid you may have overdone.

if (count > 0) {
return `${char} appears ${count} times in ${str}`;
} else {
return `no occurrences of the "${char}" were found in the "${str}"`;
}
}

module.exports = { countChar };
30 changes: 30 additions & 0 deletions Sprint-3/revise/implement/count.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,33 @@
// And a character char that does not exist within the case-sensitive str,
// When the function is called with these inputs,
// Then it should return 0, indicating that no occurrences of the char were found in the case-sensitive str.


const { countChar } = require('./count'); // Import the function from count.js

describe('countChar', () => {
test('returns correct count when the character exists in the string', () => {
expect(countChar('hello', 'l')).toBe('l appears 2 times in hello');
});

test('returns correct count when the character appears once', () => {
expect(countChar('world', 'w')).toBe('w appears 1 times in world');
});

test('returns correct message when the character does not exist in the string', () => {
expect(countChar('hello', 'z')).toBe('no occurrences of the "z" were found in the "hello"');
});

test('handles an empty string input', () => {
expect(countChar('', 'a')).toBe('no occurrences of the "a" were found in the ""');
});

test('is case-sensitive and counts only exact matches', () => {
expect(countChar('Hello', 'h')).toBe('no occurrences of the "h" were found in the "Hello"');
});

test('works correctly when the character is a space', () => {
expect(countChar('hello world', ' ')).toBe(' appears 1 times in hello world');
});
});

56 changes: 56 additions & 0 deletions Sprint-3/revise/implement/get-ordinal-number.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,59 @@

// continue testing and implementing getOrdinalNumber for additional cases
// Write your tests using Jest - remember to run your tests often for continual feedback

const getOrdinalNumber = require('./getOrdinalNumber'); // Import the function

describe('getOrdinalNumber', () => {
test('returns "1st" for input 1', () => {
expect(getOrdinalNumber(1)).toBe('1st');
});

test('returns "2nd" for input 2', () => {
expect(getOrdinalNumber(2)).toBe('2nd');
});

test('returns "3rd" for input 3', () => {
expect(getOrdinalNumber(3)).toBe('3rd');
});

test('returns "4th" for input 4', () => {
expect(getOrdinalNumber(4)).toBe('4th');
});

test('returns "11th" for input 11', () => {
expect(getOrdinalNumber(11)).toBe('11th');
});

test('returns "12th" for input 12', () => {
expect(getOrdinalNumber(12)).toBe('12th');
});

test('returns "13th" for input 13', () => {
expect(getOrdinalNumber(13)).toBe('13th');
});

test('returns "21st" for input 21', () => {
expect(getOrdinalNumber(21)).toBe('21st');
});

test('returns "22nd" for input 22', () => {
expect(getOrdinalNumber(22)).toBe('22nd');
});

test('returns "23rd" for input 23', () => {
expect(getOrdinalNumber(23)).toBe('23rd');
});

test('returns "112th" for input 112', () => {
expect(getOrdinalNumber(112)).toBe('112th');
});

test('returns "101st" for input 101', () => {
expect(getOrdinalNumber(101)).toBe('101st');
});

test('returns "103rd" for input 103', () => {
expect(getOrdinalNumber(103)).toBe('103rd');
});
});
27 changes: 27 additions & 0 deletions Sprint-3/revise/implement/getOrdinalNumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function getOrdinalNumber(number) {
const firstDigit = number % 10; // First digit of the number
const secondDigit = number % 100; // Last two digits of the number

let suffix = "th"; // Default suffix

// Handle special cases for 11th, 12th, and 13th
if (secondDigit >= 11 && secondDigit <= 13) {
return `${number}${suffix}`;
} else if (firstDigit === 1) {
suffix = "st";
} else if (firstDigit === 2) {
suffix = "nd";
} else if (firstDigit === 3) {
suffix = "rd";
}
return `${number}${suffix}`;
}

console.log(getOrdinalNumber(45)); // "45th"
console.log(getOrdinalNumber(1)); // "1st"
console.log(getOrdinalNumber(2)); // "2nd"
console.log(getOrdinalNumber(3)); // "3rd"
console.log(getOrdinalNumber(11)); // "11th"
console.log(getOrdinalNumber(112)); // "112th"

module.exports = getOrdinalNumber; // Export the function
Loading