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

CYF ITP South Africa - Cape Town | Dawud Vermeulen | Module-Structuring-and-Testing-Data | Week 3 #216

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
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
11 changes: 11 additions & 0 deletions Sprint-3/implement/angle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = function getAngleType(angle) {
if (angle === 90) return 'Right angle';
Copy link

Choose a reason for hiding this comment

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

Not wrong, but is it really best practice to use only "if" statements in this instance?

if (angle < 90) return 'Acute angle';
Copy link

Choose a reason for hiding this comment

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

Bear in mind that the code is executed line-by-line, so the function will return 'acute angle' for anything less than or equal to 0. How would you remedy this?

if (angle > 90 && angle < 180) return 'Obtuse angle';
Copy link

Choose a reason for hiding this comment

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

While this is not wrong, note that code often doesn't need everything written in explicit detail and can interpret things based on implications, so it's best to avoid redundancy to keep the code as neat and succinct as possible. Do you see which boolean in the above line of code and one of the lines below may be redundant?

if (angle === 180) return 'Straight angle';
if (angle > 180 && angle < 360) return 'Reflex angle';
if (angle <= 0 || angle >= 360) return 'Who you trying to fool Flat-Earther?!'
}

//this was the first time i followed the TDD approach and started with tests then the function. the approach works for me cause its like i know what the function must do, its more clear.
// i needed Babel to help me with the es6 as jest only uses commonJS and i ran into alot of problems getting my tests to run but in the end i discovered Babel and learnt alot of extras.
22 changes: 22 additions & 0 deletions Sprint-3/implement/angle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const getAngleType = require('./angle');
//its still js so i should be able to comment in this file. i wrote specific tests and followed the boiler plate from the site.
describe('getAngleType', () => {
it('identifies right angles', () => {
expect(getAngleType(90)).toBe('Right angle');
});
it('identifies acute angles', () => {
expect(getAngleType(45)).toBe('Acute angle');
});
it('identifies obtuse angles', () => {
expect(getAngleType(120)).toBe('Obtuse angle');
});
it('identifies straight angles', () => {
expect(getAngleType(180)).toBe('Straight angle'); // Fixed the expected value
});
it('identifies reflex angles', () => {
expect(getAngleType(270)).toBe('Reflex angle');
});
it('identifies invalid angles', () => {
expect(getAngleType(360)).toBe('Who you trying to fool Flat-Earther?!');
});
});
5 changes: 5 additions & 0 deletions Sprint-3/implement/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};

//my testing was not working cause my code was in es6 and jest speaks commonJS. i added babel to help solve this miscommunication. this code imports the function then tests. i started by writing this first to try the TDD approach.
39 changes: 39 additions & 0 deletions Sprint-3/implement/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* write a function called getCardValue(that takes in a string){
the function then matches that string to a object in the array of cards and returns the numeric value of the match.
create a array of a deck of cards. cards 2-10 of any suite have the numeric value respective numeric values 2-10. face cards of any suite have the value 10. the Ace card of any suite has the numeric value 11.
return the the int value of the card that the input string matched to.
the input must have 1 numeric value of int 2 - 10 or a face card value of K,Q,J,A. the input string must also contain an emoji for the suit, valid emojis are: ♠️,♦️,♣️,♥️
} */

module.exports = function getCardValue(card) {
const cardValues = {
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'10': 10,
'J': 10,
'Q': 10,
'K': 10,
'A': 11
};

// input validation
if (typeof card !== 'string') {
throw new Error('Invalid input: card must be a string');
}

// Extract character until we hit one thats not a number
const value = card.match(/^([0-9]+|[JQKA])/)?.[0];
// note the .match method works as expected with the string for the 1st test case. update with more test cases.
if (!value || !(value in cardValues)) {
throw new Error('Invalid input: invalid card value');
}

// If we got here, the value is valid, so return its numeric value
return cardValues[value];
}
58 changes: 58 additions & 0 deletions Sprint-3/implement/card.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// write tests for testing the user inputs
// input K♥️ expect return of int 10
// input Q expect return of a error cause no emoji for suit entered
// input J♣️ expect return of int 10
//input 4♠️ expect return of int 4
// input A♦️ expect return of int 11
// input 1♣️ expect return of error message "Invalid entry"
// input ♥️♥️ expect a return of error message "Invalid entry"

const getCardValue = require('./card');

describe('getCardValue', () => {
// write 1 test case just to check jest works. it is expected to fail.
it('should return 10 for King of any suit', () => {
expect(getCardValue('K♥️')).toBe(10);
});
// Test Ace's
test('should return 11 for Ace of any suit', () => {
expect(getCardValue('A♠️')).toBe(11);
expect(getCardValue('A♥️')).toBe(11);
expect(getCardValue('A♦️')).toBe(11);
expect(getCardValue('A♣️')).toBe(11);
});

// Test face's
test.each([
['J♠️', 10],
['Q♥️', 10],
['K♦️', 10],
])('should return 10 for face card %s', (input, expected) => {
expect(getCardValue(input)).toBe(expected);
});

// Tests number cards
test.each([
['2♠️', 2],
['3♥️', 3],
['4♦️', 4],
['5♣️', 5],
['6♠️', 6],
['7♥️', 7],
['8♦️', 8],
['9♣️', 9],
['10♠️', 10],
])('should return %i for card %s', (input, expected) => {
expect(getCardValue(input)).toBe(expected);
});

// Test error cases

test('should throw error for non-string input', () => {
expect(() => getCardValue(42)).toThrow('Invalid input: card must be a string');
expect(() => getCardValue(null)).toThrow('Invalid input: card must be a string');
//expect(() => getCardValue('A')).toThrow('Invalid input: card must be a string'); // test case does not work. error with .toThrow method
});


});
1 change: 1 addition & 0 deletions Sprint-3/implement/get-card-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// 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),
// so just off the cuff this sounds like a array for the cards. maybe make them all objects.
// When the function getCardValue is called with this card string as input,
// Then it should return the numerical card value

Expand Down
29 changes: 29 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,32 @@
// 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.
/*
so we making a function to check if its a fraction, start like the previous two, TDD. write the tests and the basic boiler of what i know for sure then work backwards it somehow works better.
def isProperFraction(numerator(int), denominator(int)){
if numerator< denominator return true
else false}

jest9copied from previous code and just adapted but we should work these over for more errors:
describe('isProperFraction', () => {
it('identifies if it is a proper fraction', () => {
expect(isProperFraction(0,-1)).toBe('false');
});
it('identifies if it is a proper fraction', () => {
expect(isProperFraction(10,100)).toBe('true');
});
it('identifies if it is a proper fraction', () => {
expect(isProperFraction(50,50.7)).toBe('true');
});
it('identifies that this is not a fraction', () => {
expect(isProperFraction(-13,13)).toBe('false'); // Fixed the expected value
});
it('identifies reflex angles', () => {
expect(isProperFraction(-n,E)).toBe('true');
});
it('identifies invalid angles', () => {
expect(isProperFraction(x,y)).toBe('true');
});
});

*/
24 changes: 24 additions & 0 deletions Sprint-3/implement/isProperFraction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// here is my 1st attempt a the solution:
/*
function isProperFraction(numerator, denominator) {
if (numerator < denominator) {
return true;
} else {
return false;
}
}
*/
// lets call this one v2 of the function
function isProperFraction(numerator, denominator) {
if (denominator === 0) {
throw new Error("Denominator cannot be zero");
}

if (Math.abs(numerator) < Math.abs(denominator)) { // v2 fails a test here. it should consider the absolute value of the numerator and denominator and so i changed it but lets get the syntax right.
return true;
} else {
return false;
}
}

module.exports = isProperFraction;
38 changes: 38 additions & 0 deletions Sprint-3/implement/isProperFraction.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const isProperFraction = require('./isProperFraction');

// i think i can improve these maybe but lets run it against the 1st iteration of the function (i already got a better slicker approach in mind)
describe('isProperFraction', () => {
test('identifies a basic proper fraction', () => {
expect(isProperFraction(2, 3)).toBe(true);
});

test('identifies an improper fraction', () => {
expect(isProperFraction(5, 2)).toBe(false);
});

test('throws error for zero denominator', () => {
expect(() => isProperFraction(3, 0)).toThrow('Denominator cannot be zero'); //BUG v1 does not handle the user input error of a zero denominator. test fails.
});

test('handles negative proper fraction', () => {
expect(isProperFraction(-4, 7)).toBe(true);
});

test('returns false when numerator equals denominator', () => {
expect(isProperFraction(3, 3)).toBe(false);
});

test('handles zero numerator', () => {
expect(isProperFraction(0, 5)).toBe(true);
});

test('works with large numbers', () => {
expect(isProperFraction(99, 100)).toBe(true);
expect(isProperFraction(100, 99)).toBe(false);
});

test('handles negative denominator', () => {
expect(isProperFraction(2, -7)).toBe(true); //BUG for the test of v1 of the function this fails and returns 'false'.
expect(isProperFraction(-2, -7)).toBe(true); //on v2 this fails but its !=BUG=! cause i got it wrong it should be changed to 'true' as the input would evaluate to a positive fraction of 2 over 7.
});
});
6 changes: 6 additions & 0 deletions Sprint-3/implement/rotate-char.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
// Given a character and a shift value,
// When the function rotateCharacter is called with these inputs,
// Then it should:
//okay i think i get it. the function rotateChar must take in the first argument char and then the second argument is a int.
// the function finds the position of the char in the alphabet then adds the int argument to it and then return the new char from the alphabet


// Scenario: Rotate Lowercase Letters:
// Given a lowercase letter character and a positive integer shift,
Expand Down Expand Up @@ -41,3 +44,6 @@ console.log(rotateCharacter("7", 5)); // Output: "7" (unchanged, not a letter)
// 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)

//okay i think i get it. the function rotateChar must take in the first argument char and then the second argument is a int.
// the function finds the position of the char in the alphabet then adds the int argument to it and then return the new char from the alphabet
26 changes: 26 additions & 0 deletions Sprint-3/implement/rotateCharacter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// this one feels tricky so the code is simple and easy to understand. i will research a better way for v2 but following my initial breakdown and using the ternary is the best i can do for v1

function rotateCharacter(char, shift) {
// If != letter, return the char as is
if (!/[a-zA-Z]/.test(char)) {
return char;
}

// uppercase or lowercase?
const isUpperCase = char === char.toUpperCase();

// Sets starting point of the alphabet
const alphabet = isUpperCase //refactored cause extra var not necessary
? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
: 'abcdefghijklmnopqrstuvwxyz';

// Find index of the char in the alphabet
const currentIndex = alphabet.indexOf(char);

// Calculate the new index
const newIndex = (currentIndex + shift + 26) % 26;

return alphabet[newIndex];
}

module.exports = rotateCharacter;
39 changes: 39 additions & 0 deletions Sprint-3/implement/rotateCharacter.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//just copied the test cases from the spec
const rotateCharacter = require('./rotateCharacter');

describe('rotateCharacter', () => {
// Lowercase
test('rotates lowercase letters', () => {
expect(rotateCharacter("a", 3)).toBe("d");
expect(rotateCharacter("f", 1)).toBe("g");
});

// Uppercase
test('rotates uppercase letters', () => {
expect(rotateCharacter("A", 3)).toBe("D");
expect(rotateCharacter("F", 1)).toBe("G");
});

// Wraparound alphabet. this is a issue.
test('handles wraparound for lowercase', () => {
expect(rotateCharacter("z", 1)).toBe("a");
expect(rotateCharacter("x", 5)).toBe("c");
});

test('handles wraparound for uppercase', () => {
expect(rotateCharacter("Z", 1)).toBe("A");
expect(rotateCharacter("Y", 2)).toBe("A");
});

// Non-letter
test('leaves non-letter characters unchanged', () => {
expect(rotateCharacter("7", 5)).toBe("7");
expect(rotateCharacter("!", 3)).toBe("!");
});

// Negative shifts. another area that needs attention.
test('handles negative shifts', () => {
expect(rotateCharacter("d", -1)).toBe("c");
expect(rotateCharacter("A", -1)).toBe("Z");
});
});
8 changes: 8 additions & 0 deletions Sprint-3/revise/implement/card-validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ These are the requirements your project needs to fulfill:
- Return a boolean from the function to indicate whether the credit card number is valid.

Good luck!

/*
- touch command to create file cardValidator.js
- define a function cardValidator(cardNumber16digits){}
- // this function checks if the card number entered by a user is valid.
- // a valid card number has the following parameters: 16 digits, ends in even number so use %2 if ==0 then even, if cardNumber sum > 16 card is valid.
- function ends in return boolean if card is valid(true) or invalid(false)
*/
6 changes: 6 additions & 0 deletions Sprint-3/revise/implement/cardValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function cardValidator(cardNumber){
Copy link

Choose a reason for hiding this comment

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

Where are the contents of the function?

// this function checks if the card number entered by a user is valid.
// a valid card number has the following parameters: 16 digits, ends in even number so use %2 if ==0 then even, if cardNumber sum > 16 card is valid.
// a conditional statement to say if the cardNumber is true or false
return validCard //this is a true or false to show if the card is valid
}
16 changes: 16 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,19 @@
// 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.


/*
create a function called countChar(str, char) the str is changed to lowercase.
the char is used to search the string for its match and if present a increment a var for count.
the return will be the count and a string giving a brief report of the findings.

i can write the test cases in this file but the requirements didnt actually ask for tests but guess its implied so lets get a basic test

const str = "targeted character";
const charToCount = 'a';
const result = countChar(str, charToCount);
console.log(result);

we expect to get a result of `$result`
*/
Loading