From 5bf5416aadd23a6bcb4bd7bcbac48827840964de Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 2 Dec 2025 11:36:09 +0100 Subject: [PATCH 1/9] 1-key-errors - 0 let this let statement is trying to declare a variable with the same name as the function parameter - 1 const decimalNumber = 0.5; and callin the function, for example console.log(convertToPercentage(0.75)); // 75% - 2 square(num) { // changed parameter name from 3 to num. console.log(square(4)); // 16 --- Sprint-2/1-key-errors/0.js | 21 +++++++++++++++++---- Sprint-2/1-key-errors/1.js | 23 +++++++++++++++++------ Sprint-2/1-key-errors/2.js | 10 ++++++++-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Sprint-2/1-key-errors/0.js b/Sprint-2/1-key-errors/0.js index 653d6f5a0..837838d61 100644 --- a/Sprint-2/1-key-errors/0.js +++ b/Sprint-2/1-key-errors/0.js @@ -1,13 +1,26 @@ // Predict and explain first... // =============> write your prediction here +// this let statement is trying to declare a variable with the same name as the function parameter 'str', +// which will cause a syntax error because you cannot redeclare a parameter within the same scope. + // call the function capitalise with a string input + +// we don't call the function here, but if we did, it would result in an error due to the redeclaration of 'str'. // interpret the error message and figure out why an error is occurring -function capitalise(str) { - let str = `${str[0].toUpperCase()}${str.slice(1)}`; - return str; -} +// function capitalise(str) { +// let str = `${str[0].toUpperCase()}${str.slice(1)}`; +// return str; +// } // =============> write your explanation here // =============> write your new code here + + +function capitalise(str) { + str = `${str[0].toUpperCase()}${str.slice(1)}`; + return str; +} +console.log(capitalise('hello')); +// Hello \ No newline at end of file diff --git a/Sprint-2/1-key-errors/1.js b/Sprint-2/1-key-errors/1.js index f2d56151f..fc9b59580 100644 --- a/Sprint-2/1-key-errors/1.js +++ b/Sprint-2/1-key-errors/1.js @@ -1,20 +1,31 @@ // Predict and explain first... // Why will an error occur when this program runs? +// SyntaxError: Identifier 'decimalNumber' has already been declared +// We don't need to redeclare the variable decimalNumber inside the function because it's already declared as a +// parameter. This causes a conflict in the scope of the function. // =============> write your prediction here // Try playing computer with the example to work out what is going on -function convertToPercentage(decimalNumber) { - const decimalNumber = 0.5; - const percentage = `${decimalNumber * 100}%`; +// function convertToPercentage(decimalNumber) { +// const decimalNumber = 0.5; +// const percentage = `${decimalNumber * 100}%`; - return percentage; -} +// return percentage; +// } -console.log(decimalNumber); +// console.log(decimalNumber); // =============> write your explanation here // Finally, correct the code to fix the problem // =============> write your new code here + +function convertToPercentage(decimalNumber) { + const percentage = `${decimalNumber * 100}%`; + return percentage; +} +console.log(convertToPercentage(0.75)); // 75% +console.log(convertToPercentage(0.2)); // 20% +console.log(convertToPercentage(0.5)); // 50% \ No newline at end of file diff --git a/Sprint-2/1-key-errors/2.js b/Sprint-2/1-key-errors/2.js index aad57f7cf..91492d6f4 100644 --- a/Sprint-2/1-key-errors/2.js +++ b/Sprint-2/1-key-errors/2.js @@ -1,15 +1,21 @@ // Predict and explain first BEFORE you run any code... - +// We neet to call the function square with a number argument, and change the parameter name to a num here. // this function should square any number but instead we're going to get an error // =============> write your prediction of the error here -function square(3) { +function square(num) { // changed parameter name from 3 to num return num * num; } +console.log(square(4)); // 16 +console.log(square(10)); // =============> write the error message here +// function square(3) { +// ^ + +// SyntaxError: Unexpected number // =============> explain this error message here From dc520df63e12d661b02ac73ce9ea7fa3a77a6d79 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 2 Dec 2025 12:37:09 +0100 Subject: [PATCH 2/9] 2-mandatory-debug 1 - replaced console.log in to return 2 - removed semicolom after return statement and retuned sum of a and b 3 - added argument for function. - replaced num in to a argument inside the function --- Sprint-2/2-mandatory-debug/0.js | 6 ++++-- Sprint-2/2-mandatory-debug/1.js | 5 +++-- Sprint-2/2-mandatory-debug/2.js | 14 ++++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Sprint-2/2-mandatory-debug/0.js b/Sprint-2/2-mandatory-debug/0.js index b27511b41..aeb2ecb5d 100644 --- a/Sprint-2/2-mandatory-debug/0.js +++ b/Sprint-2/2-mandatory-debug/0.js @@ -1,9 +1,10 @@ // Predict and explain first... // =============> write your prediction here - +// We're going to get 320 and 'The result of multiplying 10 and 32 is undefined' +// because the multiply function does not return a value; it only logs the product to the console. function multiply(a, b) { - console.log(a * b); + return (a * b); } console.log(`The result of multiplying 10 and 32 is ${multiply(10, 32)}`); @@ -12,3 +13,4 @@ console.log(`The result of multiplying 10 and 32 is ${multiply(10, 32)}`); // Finally, correct the code to fix the problem // =============> write your new code here +// we have to replace console.log with return in the multiply function diff --git a/Sprint-2/2-mandatory-debug/1.js b/Sprint-2/2-mandatory-debug/1.js index 37cedfbcf..6f0bc319d 100644 --- a/Sprint-2/2-mandatory-debug/1.js +++ b/Sprint-2/2-mandatory-debug/1.js @@ -1,9 +1,9 @@ // Predict and explain first... // =============> write your prediction here +// We're going to get undefined because the sum function has a return statement that does not return any value. function sum(a, b) { - return; - a + b; + return a + b; } console.log(`The sum of 10 and 32 is ${sum(10, 32)}`); @@ -11,3 +11,4 @@ console.log(`The sum of 10 and 32 is ${sum(10, 32)}`); // =============> write your explanation here // Finally, correct the code to fix the problem // =============> write your new code here +// we just remove the semicolon after return statement and return the sum of a and b diff --git a/Sprint-2/2-mandatory-debug/2.js b/Sprint-2/2-mandatory-debug/2.js index 57d3f5dc3..5f2d702de 100644 --- a/Sprint-2/2-mandatory-debug/2.js +++ b/Sprint-2/2-mandatory-debug/2.js @@ -2,11 +2,16 @@ // Predict the output of the following code: // =============> Write your prediction here - +// The output will be: +// The last digit of 42 is 3 +// The last digit of 105 is 3 +// The last digit of 806 is 3 +// because the function getLastDigit always returns the last digit of the constant variable num which is set to 103. const num = 103; -function getLastDigit() { - return num.toString().slice(-1); +function getLastDigit(a) { + return a.toString().slice(-1); + } console.log(`The last digit of 42 is ${getLastDigit(42)}`); @@ -19,6 +24,7 @@ console.log(`The last digit of 806 is ${getLastDigit(806)}`); // =============> write your explanation here // Finally, correct the code to fix the problem // =============> write your new code here - +// now it's working properly because we are returning the last digit of the argument a passed to the function getLastDigit +// instead of the constant variable num. // This program should tell the user the last digit of each number. // Explain why getLastDigit is not working properly - correct the problem From 11fcb90ca257b06ba32f2ad737335f8aeb88a8ef Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 2 Dec 2025 20:20:06 +0100 Subject: [PATCH 3/9] 3 - mandatory - implement 1. - made function to calculate the BMI - created a variable for call the function 2. - created a function for make it toUpperSnakeCase and added few tests 3. - function for pounds - practiced in methods substring, padStart, padEnd - added console.log as tests --- Sprint-2/3-mandatory-implement/1-bmi.js | 8 +++++++- Sprint-2/3-mandatory-implement/2-cases.js | 9 +++++++++ Sprint-2/3-mandatory-implement/3-to-pounds.js | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Sprint-2/3-mandatory-implement/1-bmi.js b/Sprint-2/3-mandatory-implement/1-bmi.js index 17b1cbde1..0d269bc13 100644 --- a/Sprint-2/3-mandatory-implement/1-bmi.js +++ b/Sprint-2/3-mandatory-implement/1-bmi.js @@ -15,5 +15,11 @@ // It should return their Body Mass Index to 1 decimal place function calculateBMI(weight, height) { + const bmi = weight / (height * height); + return parseFloat(bmi.toFixed(1)); // return the BMI of someone based off their weight and height -} \ No newline at end of file +} +const yourBMI = calculateBMI(70, 1.73); +console.log(`Your BMI is ${yourBMI}`); // Your BMI is 23.4 +const anotherBMI = calculateBMI(95, 1.88); +console.log(`Another person's BMI is ${anotherBMI}`); // Another person's BMI is 26.8 diff --git a/Sprint-2/3-mandatory-implement/2-cases.js b/Sprint-2/3-mandatory-implement/2-cases.js index 5b0ef77ad..1b2363e6a 100644 --- a/Sprint-2/3-mandatory-implement/2-cases.js +++ b/Sprint-2/3-mandatory-implement/2-cases.js @@ -14,3 +14,12 @@ // You will need to come up with an appropriate name for the function // Use the MDN string documentation to help you find a solution // This might help https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase + +function toUpperSnakeCase(str) { + return str.toUpperCase().replace(/ /g, '_'); + +} + +console.log(toUpperSnakeCase('hello there')); // "HELLO_THERE" +console.log(toUpperSnakeCase('lord of the rings')); // "LORD_OF_THE_RINGS" +console.log(toUpperSnakeCase('JavaScript is fun')); // "JAVASCRIPT_IS_FUN" diff --git a/Sprint-2/3-mandatory-implement/3-to-pounds.js b/Sprint-2/3-mandatory-implement/3-to-pounds.js index 6265a1a70..7fc6519c3 100644 --- a/Sprint-2/3-mandatory-implement/3-to-pounds.js +++ b/Sprint-2/3-mandatory-implement/3-to-pounds.js @@ -4,3 +4,22 @@ // You will need to declare a function called toPounds with an appropriately named parameter. // You should call this function a number of times to check it works for different inputs + + +function toPounds(penceString) { + // return the amount in pounds and pence format + const penceStringWithoutTrailingP = penceString.substring(0, penceString.length - 1); + // Ensure at least 3 digits for correct slicing + const paddedPenceNumberString = penceStringWithoutTrailingP.padStart(3, "0"); + // Split into pounds and pence + const pounds = paddedPenceNumberString.substring(0, paddedPenceNumberString.length - 2); + // Get last two digits for pence + const pence = paddedPenceNumberString.substring(paddedPenceNumberString.length - 2).padEnd(2, "0"); + + return `£${pounds}.${pence}`; + } + +console.log(toPounds("399p")); // £3.99 +console.log(toPounds("50p")); // £0.50 +console.log(toPounds("5p")); // £0.05 +console.log(toPounds("1234p")); // £12.34 \ No newline at end of file From f283be6bbda4d79ffd531b6cab82e9ccc75390a5 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 5 Dec 2025 14:33:20 +0100 Subject: [PATCH 4/9] checked the folder 4 - experimented with the file time-format, and before that created time function which works for 23:59 format --- Sprint-2/4-mandatory-interpret/time-format.js | 9 ++ Sprint-2/4-mandatory-interpret/time.js | 23 ++++ python/intro_canvas.py | 105 ++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 Sprint-2/4-mandatory-interpret/time.js create mode 100644 python/intro_canvas.py diff --git a/Sprint-2/4-mandatory-interpret/time-format.js b/Sprint-2/4-mandatory-interpret/time-format.js index 7c98eb0e8..661e67f6a 100644 --- a/Sprint-2/4-mandatory-interpret/time-format.js +++ b/Sprint-2/4-mandatory-interpret/time-format.js @@ -7,9 +7,11 @@ function formatTimeDisplay(seconds) { const totalMinutes = (seconds - remainingSeconds) / 60; const remainingMinutes = totalMinutes % 60; const totalHours = (totalMinutes - remainingMinutes) / 60; + console.log(totalHours); return `${pad(totalHours)}:${pad(remainingMinutes)}:${pad(remainingSeconds)}`; } +console.log(formatTimeDisplay(12345)); // You will need to play computer with this example - use the Python Visualiser https://pythontutor.com/visualize.html#mode=edit // to help you answer these questions @@ -18,17 +20,24 @@ function formatTimeDisplay(seconds) { // a) When formatTimeDisplay is called how many times will pad be called? // =============> write your answer here +// 3 times + // Call formatTimeDisplay with an input of 61, now answer the following: // b) What is the value assigned to num when pad is called for the first time? // =============> write your answer here +// 0 (when calculating hours) // c) What is the return value of pad is called for the first time? // =============> write your answer here +// "00" // d) What is the value assigned to num when pad is called for the last time in this program? Explain your answer // =============> write your answer here +// 1 (when calculating seconds) + // e) What is the return value assigned to num when pad is called for the last time in this program? Explain your answer // =============> write your answer here +// "01" (when calculating seconds) diff --git a/Sprint-2/4-mandatory-interpret/time.js b/Sprint-2/4-mandatory-interpret/time.js new file mode 100644 index 000000000..0e82224e5 --- /dev/null +++ b/Sprint-2/4-mandatory-interpret/time.js @@ -0,0 +1,23 @@ +function formatAs12HourClock(time) { + const [hoursStr, minutes] = time.split(":"); + const hours = parseInt(hoursStr, 10); + if (hours > 24 || minutes >= 60) { + throw new Error("Invalid time format"); + } + if (hours >= 12) { + const adjustedHours = hours > 12 ? hours - 12 : hours; + return `${adjustedHours}:${minutes} pm`; + } else { + return `${hours}:${minutes} am`; + } +} + +const moment = "13:45"; +console.log(formatAs12HourClock(moment)); // Output: 2:00 pm +// console.log(formatAs12HourClock("00:30")); // "12:30 am" + +// const currentOutput = formatAs12HourClock("08:00"); +// const targetOutput = "08:00 am"; +// console.assert( +// currentOutput === targetOutput, +// `current output: ${currentOutput}, target output: ${targetOutput}`); \ No newline at end of file diff --git a/python/intro_canvas.py b/python/intro_canvas.py new file mode 100644 index 000000000..dfe483935 --- /dev/null +++ b/python/intro_canvas.py @@ -0,0 +1,105 @@ +""" +This program implements an 'eraser' on a canvas. + +The canvas consists of a grid of blue 'cells' which are drawn +as rectangles on the screen. We then create an eraser rectangle +which, when dragged around the canvas, sets all of the rectangles +it is in contact with to white. +""" + +""" +This is a worked example. This code is starter code; you should edit and run it to +solve the problem. You can click the blue show solution button on the left to see +the answer if you get too stuck or want to check your work! +""" + +from graphics import Canvas +import time + +CANVAS_WIDTH = 400 +CANVAS_HEIGHT = 400 + +CELL_SIZE = 40 +ERASER_SIZE = 20 + +def erase_objects(canvas, eraser): + """Erases any objects that the eraser is touching on the canvas. + + Args: + canvas (Canvas): The canvas containing the objects to erase. + eraser (Rectangle): The rectangle representing the eraser. + """ + eraser_left = canvas.get_left_x(eraser) + eraser_top = canvas.get_top_y(eraser) + eraser_right = eraser_left + ERASER_SIZE + eraser_bottom = eraser_top + ERASER_SIZE + + # Get all objects currently on the canvas + all_objects = canvas.get_all_objects() + + for obj in all_objects: + if obj == eraser: + continue # Skip the eraser itself + + obj_left = canvas.get_left_x(obj) + obj_top = canvas.get_top_y(obj) + obj_right = obj_left + CELL_SIZE + obj_bottom = obj_top + CELL_SIZE + + # Check for overlap between the eraser and the object + if not (eraser_right < obj_left or + eraser_left > obj_right or + eraser_bottom < obj_top or + eraser_top > obj_bottom): + # There is an overlap; erase the object by setting its color to white + canvas.set_color(obj, 'white') + +# There is no need to edit code beyond this point + +def main(): + canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT) + + num_rows = CANVAS_HEIGHT // CELL_SIZE # Figure out how many rows of cells we need + num_cols = CANVAS_WIDTH // CELL_SIZE # Figure out how many columns of cells we need + + # Make a grid of squares based on the number of rows and columns. + # The rows and columns along with our cell size help determine where + # each individual cell belongs in our grid! + for row in range(num_rows): + for col in range(num_cols): + left_x = col * CELL_SIZE + top_y = row * CELL_SIZE + right_x = left_x + CELL_SIZE # The right coordinate of the cell is CELL_SIZE pixels away from the left + bottom_y = top_y + CELL_SIZE # The bottom coordinate of the cell is CELL_SIZE pixels away from the top + + # Create a single cell in the grid + cell = canvas.create_rectangle(left_x, top_y, right_x, bottom_y, 'blue') + + + canvas.wait_for_click() # Wait for the user to click before creating the eraser + + last_click_x, last_click_y = canvas.get_last_click() # Get the starting location for the eraser + + # Create our eraser + eraser = canvas.create_rectangle( + last_click_x, + last_click_y, + last_click_x + ERASER_SIZE, + last_click_y + ERASER_SIZE, + 'pink' + ) + + while True: + # Move the eraser, and erase what it's touching + + mouse_x = canvas.get_mouse_x() + mouse_y = canvas.get_mouse_y() + canvas.moveto(eraser, mouse_x, mouse_y) + + erase_objects(canvas, eraser) # We need to implement this! + + time.sleep(0.05) + + +if __name__ == '__main__': + main() \ No newline at end of file From 86b4e3391990591e1327a88fd76c79db2a22fa90 Mon Sep 17 00:00:00 2001 From: Roman Date: Sat, 6 Dec 2025 14:18:38 +0100 Subject: [PATCH 5/9] codewars experience - created phone number used slice and join methods - worked with objects and types --- Sprint-2/codewars/Create Phone Number.js | 16 +++++++++++ Sprint-2/codewars/Fun with ES6 Classes.js | 15 ++++++++++ Sprint-2/codewars/Fun with ES6 Classes.ts | 34 +++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 Sprint-2/codewars/Create Phone Number.js create mode 100644 Sprint-2/codewars/Fun with ES6 Classes.js create mode 100644 Sprint-2/codewars/Fun with ES6 Classes.ts diff --git a/Sprint-2/codewars/Create Phone Number.js b/Sprint-2/codewars/Create Phone Number.js new file mode 100644 index 000000000..0e3e6b0d0 --- /dev/null +++ b/Sprint-2/codewars/Create Phone Number.js @@ -0,0 +1,16 @@ +function createPhoneNumber(numbers) { + const area = numbers.slice(0, 3).join(''); + const middle = numbers.slice(3, 6).join(''); + const last = numbers.slice(6).join(''); + + return `(${area}) ${middle}-${last}`; +} + + +console.assert(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) === '(123) 456-7890', 'Test Case 1 Failed'); +console.assert(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) === '(012) 345-6789', 'Test Case 2 Failed'); + + + +console.log(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])); // Output: (123) 456-7890 +console.log(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); // Output: (012) 345-6789 diff --git a/Sprint-2/codewars/Fun with ES6 Classes.js b/Sprint-2/codewars/Fun with ES6 Classes.js new file mode 100644 index 000000000..54297c7a2 --- /dev/null +++ b/Sprint-2/codewars/Fun with ES6 Classes.js @@ -0,0 +1,15 @@ +class Person { + constructor(firstName = 'John', lastName = 'Doe', age = 0, gender = 'Male') { + Object.assign(this, { firstName, lastName, age, gender }); + } + sayFullName() { + return `${this.firstName} ${this.lastName}`; + } + static greetExtraTerrestrials(raceName) { + return `Welcome to Planet Earth ${raceName}`; + } +} +const person1 = new Person('Roman', 'Pavlenko', 36, 'Male'); +console.log(person1.sayFullName()); // Output: Jane Doe + +console.log(Person.greetExtraTerrestrials('Martians')); // Output: Welcome to Planet Earth Martians \ No newline at end of file diff --git a/Sprint-2/codewars/Fun with ES6 Classes.ts b/Sprint-2/codewars/Fun with ES6 Classes.ts new file mode 100644 index 000000000..0a23cca57 --- /dev/null +++ b/Sprint-2/codewars/Fun with ES6 Classes.ts @@ -0,0 +1,34 @@ +class Human { + firstName: string; + lastName: string; + age: number; + gender: string; + + constructor( + firstName: string = "John", + lastName: string = "Doe", + age: number = 0, + gender: string = "Male" + ) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.gender = gender; + } + + sayFullName(): string { + return `${this.firstName} ${this.lastName}`; + } + + static greetExtraTerrestrials(raceName: string): string { + return `Welcome to Planet Earth ${raceName}`; + } +} + +// Example usage +const roman = new Person("Roman", "Pavlenko", 36, "Male"); +console.log(roman.sayFullName()); +// Output: Roman Pavlenko + +console.log(Person.greetExtraTerrestrials("Martians")); +// Output: Welcome to Planet Earth Martians From 030df398be631b0483832f7c26dae60401611621 Mon Sep 17 00:00:00 2001 From: Roman Date: Sat, 6 Dec 2025 14:23:05 +0100 Subject: [PATCH 6/9] codewars exercises - arrow function. length with the filter method to count the number of developers who met the conditions - and basic one with switch case operators - split solt join methods in function descendingOrder --- Sprint-2/codewars/Fun with ES6 Classes | 34 +++++++++++ Sprint-2/codewars/objects in javascript.js | 67 ++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Sprint-2/codewars/Fun with ES6 Classes create mode 100644 Sprint-2/codewars/objects in javascript.js diff --git a/Sprint-2/codewars/Fun with ES6 Classes b/Sprint-2/codewars/Fun with ES6 Classes new file mode 100644 index 000000000..0a23cca57 --- /dev/null +++ b/Sprint-2/codewars/Fun with ES6 Classes @@ -0,0 +1,34 @@ +class Human { + firstName: string; + lastName: string; + age: number; + gender: string; + + constructor( + firstName: string = "John", + lastName: string = "Doe", + age: number = 0, + gender: string = "Male" + ) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.gender = gender; + } + + sayFullName(): string { + return `${this.firstName} ${this.lastName}`; + } + + static greetExtraTerrestrials(raceName: string): string { + return `Welcome to Planet Earth ${raceName}`; + } +} + +// Example usage +const roman = new Person("Roman", "Pavlenko", 36, "Male"); +console.log(roman.sayFullName()); +// Output: Roman Pavlenko + +console.log(Person.greetExtraTerrestrials("Martians")); +// Output: Welcome to Planet Earth Martians diff --git a/Sprint-2/codewars/objects in javascript.js b/Sprint-2/codewars/objects in javascript.js new file mode 100644 index 000000000..30f31ecea --- /dev/null +++ b/Sprint-2/codewars/objects in javascript.js @@ -0,0 +1,67 @@ +const list1 = [ + { firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'JavaScript' }, + { firstName: 'Maia', lastName: 'S.', country: 'Tahiti', continent: 'Oceania', age: 28, language: 'JavaScript' }, + { firstName: 'Shufen', lastName: 'L.', country: 'Taiwan', continent: 'Asia', age: 35, language: 'HTML' }, + { firstName: 'Sumayah', lastName: 'M.', country: 'Tajikistan', continent: 'Asia', age: 30, language: 'CSS' }, + { firstName: 'Fatima', lastName: 'K.', country: 'Saudi Arabia', continent: 'Asia', age: 25, language: 'JavaScript' }, + { firstName: 'Agustin', lastName: 'V.', country: 'Spain', continent: 'Europe', age: 37, language: 'JavaScript' }, + ]; +function getFirstEuropeanJSDevIndex(list) { + for (let i = 0; i < list.length; i++) { + if (list[i].continent === 'Europe' && list[i].language === 'JavaScript') { + return i; + } + } + return 0; +} + +function countDevelopers(list) { + return list.filter(dev => dev.continent === 'Europe' && dev.language === 'JavaScript').length; +} + +console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); +console.log(countDevelopers(list1)); + + +function greetDevelopers(list) { + return list.map(dev => { + return { ...dev, greeting: `Hi ${dev.firstName}, what do you like the most about ${dev.language}?` }; + }); +} + +console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); + +function basicOp(operation, value1, value2) { + switch (operation) { + case '+': + return value1 + value2; + case '-': + return value1 - value2; + case '*': + return value1 * value2; + case '/': + return value1 / value2; + default: + return 0; + } +} +console.log(basicOp('+', 4, 7)); +console.log(basicOp('-', 15, 18)); +console.log(basicOp('*', 5, 5)); +console.log(basicOp('/', 49, 7)); + + +function descendingOrder(n) { + return Number(n.toString() + .split('') // convert to string and split into array + .sort((a, b) => b - a) // sort in descending order + .join('')); // join back into string and convert to number +} +console.log(descendingOrder(42145)); // Output: 54421 +console.log(descendingOrder(145263)); // Output: 654321 + +let a = (123456789).toString().split(''); +console.log(a); + + + From 215b33a154deb34d113e71bde393a07396623fab Mon Sep 17 00:00:00 2001 From: DraftRoman Date: Tue, 9 Dec 2025 16:33:18 +0100 Subject: [PATCH 7/9] Finish sprint 2 tasks --- Sprint-2/4-mandatory-interpret/time-format.js | 86 +++++------ Sprint-2/4-mandatory-interpret/time.js | 44 +++--- Sprint-2/codewars/Create Phone Number.js | 32 ++--- Sprint-2/codewars/Fun with ES6 Classes | 68 ++++----- Sprint-2/codewars/Fun with ES6 Classes.js | 28 ++-- Sprint-2/codewars/Fun with ES6 Classes.ts | 68 ++++----- Sprint-2/codewars/objects in javascript.js | 134 +++++++++--------- 7 files changed, 230 insertions(+), 230 deletions(-) diff --git a/Sprint-2/4-mandatory-interpret/time-format.js b/Sprint-2/4-mandatory-interpret/time-format.js index 661e67f6a..1bbc2fe48 100644 --- a/Sprint-2/4-mandatory-interpret/time-format.js +++ b/Sprint-2/4-mandatory-interpret/time-format.js @@ -1,43 +1,43 @@ -function pad(num) { - return num.toString().padStart(2, "0"); -} - -function formatTimeDisplay(seconds) { - const remainingSeconds = seconds % 60; - const totalMinutes = (seconds - remainingSeconds) / 60; - const remainingMinutes = totalMinutes % 60; - const totalHours = (totalMinutes - remainingMinutes) / 60; - console.log(totalHours); - - return `${pad(totalHours)}:${pad(remainingMinutes)}:${pad(remainingSeconds)}`; -} -console.log(formatTimeDisplay(12345)); - -// You will need to play computer with this example - use the Python Visualiser https://pythontutor.com/visualize.html#mode=edit -// to help you answer these questions - -// Questions - -// a) When formatTimeDisplay is called how many times will pad be called? -// =============> write your answer here -// 3 times - - -// Call formatTimeDisplay with an input of 61, now answer the following: - -// b) What is the value assigned to num when pad is called for the first time? -// =============> write your answer here -// 0 (when calculating hours) - -// c) What is the return value of pad is called for the first time? -// =============> write your answer here -// "00" - -// d) What is the value assigned to num when pad is called for the last time in this program? Explain your answer -// =============> write your answer here -// 1 (when calculating seconds) - - -// e) What is the return value assigned to num when pad is called for the last time in this program? Explain your answer -// =============> write your answer here -// "01" (when calculating seconds) +function pad(num) { + return num.toString().padStart(2, "0"); +} + +function formatTimeDisplay(seconds) { + const remainingSeconds = seconds % 60; + const totalMinutes = (seconds - remainingSeconds) / 60; + const remainingMinutes = totalMinutes % 60; + const totalHours = (totalMinutes - remainingMinutes) / 60; + console.log(totalHours); + + return `${pad(totalHours)}:${pad(remainingMinutes)}:${pad(remainingSeconds)}`; +} +console.log(formatTimeDisplay(12345)); + +// You will need to play computer with this example - use the Python Visualiser https://pythontutor.com/visualize.html#mode=edit +// to help you answer these questions + +// Questions + +// a) When formatTimeDisplay is called how many times will pad be called? +// =============> write your answer here +// 3 times + + +// Call formatTimeDisplay with an input of 61, now answer the following: + +// b) What is the value assigned to num when pad is called for the first time? +// =============> write your answer here +// 0 (when calculating hours) + +// c) What is the return value of pad is called for the first time? +// =============> write your answer here +// "00" + +// d) What is the value assigned to num when pad is called for the last time in this program? Explain your answer +// =============> write your answer here +// 1 (when calculating seconds) + + +// e) What is the return value assigned to num when pad is called for the last time in this program? Explain your answer +// =============> write your answer here +// "01" (when calculating seconds) diff --git a/Sprint-2/4-mandatory-interpret/time.js b/Sprint-2/4-mandatory-interpret/time.js index 0e82224e5..29fa49663 100644 --- a/Sprint-2/4-mandatory-interpret/time.js +++ b/Sprint-2/4-mandatory-interpret/time.js @@ -1,23 +1,23 @@ -function formatAs12HourClock(time) { - const [hoursStr, minutes] = time.split(":"); - const hours = parseInt(hoursStr, 10); - if (hours > 24 || minutes >= 60) { - throw new Error("Invalid time format"); - } - if (hours >= 12) { - const adjustedHours = hours > 12 ? hours - 12 : hours; - return `${adjustedHours}:${minutes} pm`; - } else { - return `${hours}:${minutes} am`; - } -} - -const moment = "13:45"; -console.log(formatAs12HourClock(moment)); // Output: 2:00 pm -// console.log(formatAs12HourClock("00:30")); // "12:30 am" - -// const currentOutput = formatAs12HourClock("08:00"); -// const targetOutput = "08:00 am"; -// console.assert( -// currentOutput === targetOutput, +function formatAs12HourClock(time) { + const [hoursStr, minutes] = time.split(":"); + const hours = parseInt(hoursStr, 10); + if (hours > 24 || minutes >= 60) { + throw new Error("Invalid time format"); + } + if (hours >= 12) { + const adjustedHours = hours > 12 ? hours - 12 : hours; + return `${adjustedHours}:${minutes} pm`; + } else { + return `${hours}:${minutes} am`; + } +} + +const moment = "13:45"; +console.log(formatAs12HourClock(moment)); // Output: 2:00 pm +// console.log(formatAs12HourClock("00:30")); // "12:30 am" + +// const currentOutput = formatAs12HourClock("08:00"); +// const targetOutput = "08:00 am"; +// console.assert( +// currentOutput === targetOutput, // `current output: ${currentOutput}, target output: ${targetOutput}`); \ No newline at end of file diff --git a/Sprint-2/codewars/Create Phone Number.js b/Sprint-2/codewars/Create Phone Number.js index 0e3e6b0d0..1ac967fa4 100644 --- a/Sprint-2/codewars/Create Phone Number.js +++ b/Sprint-2/codewars/Create Phone Number.js @@ -1,16 +1,16 @@ -function createPhoneNumber(numbers) { - const area = numbers.slice(0, 3).join(''); - const middle = numbers.slice(3, 6).join(''); - const last = numbers.slice(6).join(''); - - return `(${area}) ${middle}-${last}`; -} - - -console.assert(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) === '(123) 456-7890', 'Test Case 1 Failed'); -console.assert(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) === '(012) 345-6789', 'Test Case 2 Failed'); - - - -console.log(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])); // Output: (123) 456-7890 -console.log(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); // Output: (012) 345-6789 +function createPhoneNumber(numbers) { + const area = numbers.slice(0, 3).join(''); + const middle = numbers.slice(3, 6).join(''); + const last = numbers.slice(6).join(''); + + return `(${area}) ${middle}-${last}`; +} + + +console.assert(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) === '(123) 456-7890', 'Test Case 1 Failed'); +console.assert(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) === '(012) 345-6789', 'Test Case 2 Failed'); + + + +console.log(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])); // Output: (123) 456-7890 +console.log(createPhoneNumber([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); // Output: (012) 345-6789 diff --git a/Sprint-2/codewars/Fun with ES6 Classes b/Sprint-2/codewars/Fun with ES6 Classes index 0a23cca57..b83c362e0 100644 --- a/Sprint-2/codewars/Fun with ES6 Classes +++ b/Sprint-2/codewars/Fun with ES6 Classes @@ -1,34 +1,34 @@ -class Human { - firstName: string; - lastName: string; - age: number; - gender: string; - - constructor( - firstName: string = "John", - lastName: string = "Doe", - age: number = 0, - gender: string = "Male" - ) { - this.firstName = firstName; - this.lastName = lastName; - this.age = age; - this.gender = gender; - } - - sayFullName(): string { - return `${this.firstName} ${this.lastName}`; - } - - static greetExtraTerrestrials(raceName: string): string { - return `Welcome to Planet Earth ${raceName}`; - } -} - -// Example usage -const roman = new Person("Roman", "Pavlenko", 36, "Male"); -console.log(roman.sayFullName()); -// Output: Roman Pavlenko - -console.log(Person.greetExtraTerrestrials("Martians")); -// Output: Welcome to Planet Earth Martians +class Human { + firstName: string; + lastName: string; + age: number; + gender: string; + + constructor( + firstName: string = "John", + lastName: string = "Doe", + age: number = 0, + gender: string = "Male" + ) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.gender = gender; + } + + sayFullName(): string { + return `${this.firstName} ${this.lastName}`; + } + + static greetExtraTerrestrials(raceName: string): string { + return `Welcome to Planet Earth ${raceName}`; + } +} + +// Example usage +const roman = new Person("Roman", "Pavlenko", 36, "Male"); +console.log(roman.sayFullName()); +// Output: Roman Pavlenko + +console.log(Person.greetExtraTerrestrials("Martians")); +// Output: Welcome to Planet Earth Martians diff --git a/Sprint-2/codewars/Fun with ES6 Classes.js b/Sprint-2/codewars/Fun with ES6 Classes.js index 54297c7a2..17d3b8eeb 100644 --- a/Sprint-2/codewars/Fun with ES6 Classes.js +++ b/Sprint-2/codewars/Fun with ES6 Classes.js @@ -1,15 +1,15 @@ -class Person { - constructor(firstName = 'John', lastName = 'Doe', age = 0, gender = 'Male') { - Object.assign(this, { firstName, lastName, age, gender }); - } - sayFullName() { - return `${this.firstName} ${this.lastName}`; - } - static greetExtraTerrestrials(raceName) { - return `Welcome to Planet Earth ${raceName}`; - } -} -const person1 = new Person('Roman', 'Pavlenko', 36, 'Male'); -console.log(person1.sayFullName()); // Output: Jane Doe - +class Person { + constructor(firstName = 'John', lastName = 'Doe', age = 0, gender = 'Male') { + Object.assign(this, { firstName, lastName, age, gender }); + } + sayFullName() { + return `${this.firstName} ${this.lastName}`; + } + static greetExtraTerrestrials(raceName) { + return `Welcome to Planet Earth ${raceName}`; + } +} +const person1 = new Person('Roman', 'Pavlenko', 36, 'Male'); +console.log(person1.sayFullName()); // Output: Jane Doe + console.log(Person.greetExtraTerrestrials('Martians')); // Output: Welcome to Planet Earth Martians \ No newline at end of file diff --git a/Sprint-2/codewars/Fun with ES6 Classes.ts b/Sprint-2/codewars/Fun with ES6 Classes.ts index 0a23cca57..b83c362e0 100644 --- a/Sprint-2/codewars/Fun with ES6 Classes.ts +++ b/Sprint-2/codewars/Fun with ES6 Classes.ts @@ -1,34 +1,34 @@ -class Human { - firstName: string; - lastName: string; - age: number; - gender: string; - - constructor( - firstName: string = "John", - lastName: string = "Doe", - age: number = 0, - gender: string = "Male" - ) { - this.firstName = firstName; - this.lastName = lastName; - this.age = age; - this.gender = gender; - } - - sayFullName(): string { - return `${this.firstName} ${this.lastName}`; - } - - static greetExtraTerrestrials(raceName: string): string { - return `Welcome to Planet Earth ${raceName}`; - } -} - -// Example usage -const roman = new Person("Roman", "Pavlenko", 36, "Male"); -console.log(roman.sayFullName()); -// Output: Roman Pavlenko - -console.log(Person.greetExtraTerrestrials("Martians")); -// Output: Welcome to Planet Earth Martians +class Human { + firstName: string; + lastName: string; + age: number; + gender: string; + + constructor( + firstName: string = "John", + lastName: string = "Doe", + age: number = 0, + gender: string = "Male" + ) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.gender = gender; + } + + sayFullName(): string { + return `${this.firstName} ${this.lastName}`; + } + + static greetExtraTerrestrials(raceName: string): string { + return `Welcome to Planet Earth ${raceName}`; + } +} + +// Example usage +const roman = new Person("Roman", "Pavlenko", 36, "Male"); +console.log(roman.sayFullName()); +// Output: Roman Pavlenko + +console.log(Person.greetExtraTerrestrials("Martians")); +// Output: Welcome to Planet Earth Martians diff --git a/Sprint-2/codewars/objects in javascript.js b/Sprint-2/codewars/objects in javascript.js index 30f31ecea..2ef7572a4 100644 --- a/Sprint-2/codewars/objects in javascript.js +++ b/Sprint-2/codewars/objects in javascript.js @@ -1,67 +1,67 @@ -const list1 = [ - { firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'JavaScript' }, - { firstName: 'Maia', lastName: 'S.', country: 'Tahiti', continent: 'Oceania', age: 28, language: 'JavaScript' }, - { firstName: 'Shufen', lastName: 'L.', country: 'Taiwan', continent: 'Asia', age: 35, language: 'HTML' }, - { firstName: 'Sumayah', lastName: 'M.', country: 'Tajikistan', continent: 'Asia', age: 30, language: 'CSS' }, - { firstName: 'Fatima', lastName: 'K.', country: 'Saudi Arabia', continent: 'Asia', age: 25, language: 'JavaScript' }, - { firstName: 'Agustin', lastName: 'V.', country: 'Spain', continent: 'Europe', age: 37, language: 'JavaScript' }, - ]; -function getFirstEuropeanJSDevIndex(list) { - for (let i = 0; i < list.length; i++) { - if (list[i].continent === 'Europe' && list[i].language === 'JavaScript') { - return i; - } - } - return 0; -} - -function countDevelopers(list) { - return list.filter(dev => dev.continent === 'Europe' && dev.language === 'JavaScript').length; -} - -console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); -console.log(countDevelopers(list1)); - - -function greetDevelopers(list) { - return list.map(dev => { - return { ...dev, greeting: `Hi ${dev.firstName}, what do you like the most about ${dev.language}?` }; - }); -} - -console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); - -function basicOp(operation, value1, value2) { - switch (operation) { - case '+': - return value1 + value2; - case '-': - return value1 - value2; - case '*': - return value1 * value2; - case '/': - return value1 / value2; - default: - return 0; - } -} -console.log(basicOp('+', 4, 7)); -console.log(basicOp('-', 15, 18)); -console.log(basicOp('*', 5, 5)); -console.log(basicOp('/', 49, 7)); - - -function descendingOrder(n) { - return Number(n.toString() - .split('') // convert to string and split into array - .sort((a, b) => b - a) // sort in descending order - .join('')); // join back into string and convert to number -} -console.log(descendingOrder(42145)); // Output: 54421 -console.log(descendingOrder(145263)); // Output: 654321 - -let a = (123456789).toString().split(''); -console.log(a); - - - +const list1 = [ + { firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'JavaScript' }, + { firstName: 'Maia', lastName: 'S.', country: 'Tahiti', continent: 'Oceania', age: 28, language: 'JavaScript' }, + { firstName: 'Shufen', lastName: 'L.', country: 'Taiwan', continent: 'Asia', age: 35, language: 'HTML' }, + { firstName: 'Sumayah', lastName: 'M.', country: 'Tajikistan', continent: 'Asia', age: 30, language: 'CSS' }, + { firstName: 'Fatima', lastName: 'K.', country: 'Saudi Arabia', continent: 'Asia', age: 25, language: 'JavaScript' }, + { firstName: 'Agustin', lastName: 'V.', country: 'Spain', continent: 'Europe', age: 37, language: 'JavaScript' }, + ]; +function getFirstEuropeanJSDevIndex(list) { + for (let i = 0; i < list.length; i++) { + if (list[i].continent === 'Europe' && list[i].language === 'JavaScript') { + return i; + } + } + return 0; +} + +function countDevelopers(list) { + return list.filter(dev => dev.continent === 'Europe' && dev.language === 'JavaScript').length; +} + +console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); +console.log(countDevelopers(list1)); + + +function greetDevelopers(list) { + return list.map(dev => { + return { ...dev, greeting: `Hi ${dev.firstName}, what do you like the most about ${dev.language}?` }; + }); +} + +console.log(`The index of the JaveScript developer from Europe is ${getFirstEuropeanJSDevIndex(list1)}`); + +function basicOp(operation, value1, value2) { + switch (operation) { + case '+': + return value1 + value2; + case '-': + return value1 - value2; + case '*': + return value1 * value2; + case '/': + return value1 / value2; + default: + return 0; + } +} +console.log(basicOp('+', 4, 7)); +console.log(basicOp('-', 15, 18)); +console.log(basicOp('*', 5, 5)); +console.log(basicOp('/', 49, 7)); + + +function descendingOrder(n) { + return Number(n.toString() + .split('') // convert to string and split into array + .sort((a, b) => b - a) // sort in descending order + .join('')); // join back into string and convert to number +} +console.log(descendingOrder(42145)); // Output: 54421 +console.log(descendingOrder(145263)); // Output: 654321 + +let a = (123456789).toString().split(''); +console.log(a); + + + From 8dfab72391402f26ea0c032bb6b53cae8b757820 Mon Sep 17 00:00:00 2001 From: DraftRoman Date: Tue, 9 Dec 2025 16:45:12 +0100 Subject: [PATCH 8/9] intro_canvas.py --- package.json | 28 +++--- python/intro_canvas.py | 208 ++++++++++++++++++++--------------------- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/package.json b/package.json index 0657e22dd..29e7f537d 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ -{ - "name": "module-structuring-and-testing-data", - "version": "1.0.0", - "description": "Like learning a musical instrument, programming requires daily practice.", - "main": "index.js", - "scripts": { - "test": "jest" - }, - "keywords": [], - "author": "Code Your Future", - "license": "ISC", - "dependencies": { - "jest": "^29.7.0" - } +{ + "name": "module-structuring-and-testing-data", + "version": "1.0.0", + "description": "Like learning a musical instrument, programming requires daily practice.", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "Code Your Future", + "license": "ISC", + "dependencies": { + "jest": "^29.7.0" + } } \ No newline at end of file diff --git a/python/intro_canvas.py b/python/intro_canvas.py index dfe483935..92134bb83 100644 --- a/python/intro_canvas.py +++ b/python/intro_canvas.py @@ -1,105 +1,105 @@ -""" -This program implements an 'eraser' on a canvas. - -The canvas consists of a grid of blue 'cells' which are drawn -as rectangles on the screen. We then create an eraser rectangle -which, when dragged around the canvas, sets all of the rectangles -it is in contact with to white. -""" - -""" -This is a worked example. This code is starter code; you should edit and run it to -solve the problem. You can click the blue show solution button on the left to see -the answer if you get too stuck or want to check your work! -""" - -from graphics import Canvas -import time - -CANVAS_WIDTH = 400 -CANVAS_HEIGHT = 400 - -CELL_SIZE = 40 -ERASER_SIZE = 20 - -def erase_objects(canvas, eraser): - """Erases any objects that the eraser is touching on the canvas. - - Args: - canvas (Canvas): The canvas containing the objects to erase. - eraser (Rectangle): The rectangle representing the eraser. - """ - eraser_left = canvas.get_left_x(eraser) - eraser_top = canvas.get_top_y(eraser) - eraser_right = eraser_left + ERASER_SIZE - eraser_bottom = eraser_top + ERASER_SIZE - - # Get all objects currently on the canvas - all_objects = canvas.get_all_objects() - - for obj in all_objects: - if obj == eraser: - continue # Skip the eraser itself - - obj_left = canvas.get_left_x(obj) - obj_top = canvas.get_top_y(obj) - obj_right = obj_left + CELL_SIZE - obj_bottom = obj_top + CELL_SIZE - - # Check for overlap between the eraser and the object - if not (eraser_right < obj_left or - eraser_left > obj_right or - eraser_bottom < obj_top or - eraser_top > obj_bottom): - # There is an overlap; erase the object by setting its color to white - canvas.set_color(obj, 'white') - -# There is no need to edit code beyond this point - -def main(): - canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT) - - num_rows = CANVAS_HEIGHT // CELL_SIZE # Figure out how many rows of cells we need - num_cols = CANVAS_WIDTH // CELL_SIZE # Figure out how many columns of cells we need - - # Make a grid of squares based on the number of rows and columns. - # The rows and columns along with our cell size help determine where - # each individual cell belongs in our grid! - for row in range(num_rows): - for col in range(num_cols): - left_x = col * CELL_SIZE - top_y = row * CELL_SIZE - right_x = left_x + CELL_SIZE # The right coordinate of the cell is CELL_SIZE pixels away from the left - bottom_y = top_y + CELL_SIZE # The bottom coordinate of the cell is CELL_SIZE pixels away from the top - - # Create a single cell in the grid - cell = canvas.create_rectangle(left_x, top_y, right_x, bottom_y, 'blue') - - - canvas.wait_for_click() # Wait for the user to click before creating the eraser - - last_click_x, last_click_y = canvas.get_last_click() # Get the starting location for the eraser - - # Create our eraser - eraser = canvas.create_rectangle( - last_click_x, - last_click_y, - last_click_x + ERASER_SIZE, - last_click_y + ERASER_SIZE, - 'pink' - ) - - while True: - # Move the eraser, and erase what it's touching - - mouse_x = canvas.get_mouse_x() - mouse_y = canvas.get_mouse_y() - canvas.moveto(eraser, mouse_x, mouse_y) - - erase_objects(canvas, eraser) # We need to implement this! - - time.sleep(0.05) - - -if __name__ == '__main__': +""" +This program implements an 'eraser' on a canvas. + +The canvas consists of a grid of blue 'cells' which are drawn +as rectangles on the screen. We then create an eraser rectangle +which, when dragged around the canvas, sets all of the rectangles +it is in contact with to white. +""" + +""" +This is a worked example. This code is starter code; you should edit and run it to +solve the problem. You can click the blue show solution button on the left to see +the answer if you get too stuck or want to check your work! +""" + +from graphics import Canvas +import time + +CANVAS_WIDTH = 400 +CANVAS_HEIGHT = 400 + +CELL_SIZE = 40 +ERASER_SIZE = 20 + +def erase_objects(canvas, eraser): + """Erases any objects that the eraser is touching on the canvas. + + Args: + canvas (Canvas): The canvas containing the objects to erase. + eraser (Rectangle): The rectangle representing the eraser. + """ + eraser_left = canvas.get_left_x(eraser) + eraser_top = canvas.get_top_y(eraser) + eraser_right = eraser_left + ERASER_SIZE + eraser_bottom = eraser_top + ERASER_SIZE + + # Get all objects currently on the canvas + all_objects = canvas.get_all_objects() + + for obj in all_objects: + if obj == eraser: + continue # Skip the eraser itself + + obj_left = canvas.get_left_x(obj) + obj_top = canvas.get_top_y(obj) + obj_right = obj_left + CELL_SIZE + obj_bottom = obj_top + CELL_SIZE + + # Check for overlap between the eraser and the object + if not (eraser_right < obj_left or + eraser_left > obj_right or + eraser_bottom < obj_top or + eraser_top > obj_bottom): + # There is an overlap; erase the object by setting its color to white + canvas.set_color(obj, 'white') + +# There is no need to edit code beyond this point + +def main(): + canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT) + + num_rows = CANVAS_HEIGHT // CELL_SIZE # Figure out how many rows of cells we need + num_cols = CANVAS_WIDTH // CELL_SIZE # Figure out how many columns of cells we need + + # Make a grid of squares based on the number of rows and columns. + # The rows and columns along with our cell size help determine where + # each individual cell belongs in our grid! + for row in range(num_rows): + for col in range(num_cols): + left_x = col * CELL_SIZE + top_y = row * CELL_SIZE + right_x = left_x + CELL_SIZE # The right coordinate of the cell is CELL_SIZE pixels away from the left + bottom_y = top_y + CELL_SIZE # The bottom coordinate of the cell is CELL_SIZE pixels away from the top + + # Create a single cell in the grid + cell = canvas.create_rectangle(left_x, top_y, right_x, bottom_y, 'blue') + + + canvas.wait_for_click() # Wait for the user to click before creating the eraser + + last_click_x, last_click_y = canvas.get_last_click() # Get the starting location for the eraser + + # Create our eraser + eraser = canvas.create_rectangle( + last_click_x, + last_click_y, + last_click_x + ERASER_SIZE, + last_click_y + ERASER_SIZE, + 'pink' + ) + + while True: + # Move the eraser, and erase what it's touching + + mouse_x = canvas.get_mouse_x() + mouse_y = canvas.get_mouse_y() + canvas.moveto(eraser, mouse_x, mouse_y) + + erase_objects(canvas, eraser) # We need to implement this! + + time.sleep(0.05) + + +if __name__ == '__main__': main() \ No newline at end of file From 2c079198c0d4e384bd5f6dce5a4b970cce0edc81 Mon Sep 17 00:00:00 2001 From: DraftRoman Date: Tue, 9 Dec 2025 16:56:26 +0100 Subject: [PATCH 9/9] I checked Sprint 3 and now have some changes, which I don't see --- Sprint-3/1-key-implement/1-get-angle-type.js | 110 +++++++++---------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/Sprint-3/1-key-implement/1-get-angle-type.js b/Sprint-3/1-key-implement/1-get-angle-type.js index 08d1f0cba..4762c1a97 100644 --- a/Sprint-3/1-key-implement/1-get-angle-type.js +++ b/Sprint-3/1-key-implement/1-get-angle-type.js @@ -1,56 +1,56 @@ -// Implement a function getAngleType -// Build up your function case by case, writing tests as you go -// The first test and case is written for you. The next case has a test, but no code. -// Execute this script in your terminal -// node 1-get-angle-type.js -// The assertion error will tell you what the expected output is -// Write the code to pass the test -// Then, write the next test! :) Go through this process until all the cases are implemented - -function getAngleType(angle) { - if (angle === 90) return "Right angle"; - // read to the end, complete line 36, then pass your test here -} - -// we're going to use this helper function to make our assertions easier to read -// if the actual output matches the target output, the test will pass -function assertEquals(actualOutput, targetOutput) { - console.assert( - actualOutput === targetOutput, - `Expected ${actualOutput} to equal ${targetOutput}` - ); -} - -// Acceptance criteria: - -// Given an angle in degrees, -// When the function getAngleType is called with this angle, -// Then it should: - -// Case 1: Identify Right Angles: -// When the angle is exactly 90 degrees, -// Then the function should return "Right angle" -const right = getAngleType(90); -assertEquals(right, "Right angle"); - -// Case 2: Identify Acute Angles: -// When the angle is less than 90 degrees, -// Then the function should return "Acute angle" -const acute = getAngleType(45); -assertEquals(acute, "Acute angle"); - -// Case 3: Identify Obtuse Angles: -// When the angle is greater than 90 degrees and less than 180 degrees, -// Then the function should return "Obtuse angle" -const obtuse = getAngleType(120); -// ====> write your test here, and then add a line to pass the test in the function above - -// Case 4: Identify Straight Angles: -// When the angle is exactly 180 degrees, -// Then the function should return "Straight angle" -// ====> write your test here, and then add a line to pass the test in the function above - -// Case 5: Identify Reflex Angles: -// When the angle is greater than 180 degrees and less than 360 degrees, -// Then the function should return "Reflex angle" +// Implement a function getAngleType +// Build up your function case by case, writing tests as you go +// The first test and case is written for you. The next case has a test, but no code. +// Execute this script in your terminal +// node 1-get-angle-type.js +// The assertion error will tell you what the expected output is +// Write the code to pass the test +// Then, write the next test! :) Go through this process until all the cases are implemented + +function getAngleType(angle) { + if (angle === 90) return "Right angle"; + // read to the end, complete line 36, then pass your test here +} + +// we're going to use this helper function to make our assertions easier to read +// if the actual output matches the target output, the test will pass +function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); +} + +// Acceptance criteria: + +// Given an angle in degrees, +// When the function getAngleType is called with this angle, +// Then it should: + +// Case 1: Identify Right Angles: +// When the angle is exactly 90 degrees, +// Then the function should return "Right angle" +const right = getAngleType(90); +assertEquals(right, "Right angle"); + +// Case 2: Identify Acute Angles: +// When the angle is less than 90 degrees, +// Then the function should return "Acute angle" +const acute = getAngleType(45); +assertEquals(acute, "Acute angle"); + +// Case 3: Identify Obtuse Angles: +// When the angle is greater than 90 degrees and less than 180 degrees, +// Then the function should return "Obtuse angle" +const obtuse = getAngleType(120); +// ====> write your test here, and then add a line to pass the test in the function above + +// Case 4: Identify Straight Angles: +// When the angle is exactly 180 degrees, +// Then the function should return "Straight angle" +// ====> write your test here, and then add a line to pass the test in the function above + +// Case 5: Identify Reflex Angles: +// When the angle is greater than 180 degrees and less than 360 degrees, +// Then the function should return "Reflex angle" // ====> write your test here, and then add a line to pass the test in the function above \ No newline at end of file