diff --git a/animation/main.css b/animation/main.css index e69de29..3d025bc 100644 --- a/animation/main.css +++ b/animation/main.css @@ -0,0 +1,5 @@ +svg { + border: 1px solid black; + cursor: pointer; + background-color: '#E289B3' +}; \ No newline at end of file diff --git a/animation/main.js b/animation/main.js index e69de29..e3474a0 100644 --- a/animation/main.js +++ b/animation/main.js @@ -0,0 +1,102 @@ +"use strict"; + +//function animateOf(anim) { +// return setInterval(function() { +// let currSec = new Date().getSeconds() +// anim(currSec) +// }, 1000); // 1 sec +//}; + +function animateOf(anim) { + return setInterval(function() { + let epochSec = Date.now() / 1000 + anim(epochSec) + }, 1000); // 1 sec +}; + +let paper = Snap(400, 400); +let r = paper.rect(150, 100, 100, 220); +r.attr({ + fill: "transparent", + stroke: "#000", + strokeWidth: 3 +}); + +let cRed = paper.circle(200, 140, 25); +cRed.attr({ + fill: "black", + strokeWidth: 3 +}); + +let cYellow = paper.circle(200, 210, 25); +cYellow.attr({ + fill: "black", + strokeWidth: 3 +}); + +let cGreen = paper.circle(200, 280, 25); +cGreen.attr({ + fill: "black", + strokeWidth: 3 +}); +animateOf(function(t) { +let cond = (t % 9); +if ( cond >= 0 && cond < 3) { + cGreen.attr({fill: "green"}); + cYellow.attr({fill: "black"}); + cRed.attr({fill: "black"}); + } +else if ( cond >= 3 && cond < 4) { + cYellow.attr({fill: "yellow"}); + cGreen.attr({fill: "black"}); +} +else if ( cond >= 4 && cond < 7 ) { + cRed.attr({fill: "red"}); + cYellow.attr({fill: "black"}); +} +else if ( cond >= 7) { + cYellow.attr({fill: "yellow"}); +}} ); + +//if ( t % 3 == 0) { cRed.attr({fill: "red"}) } else { cRed.attr({fill: "black"}) } } ); + +let paper2 = Snap(800, 400); + +let pathStyle = { + stroke: "#222", + fill: "transparent", + strokeWidth: 1, opacity:0 +}; + +function tree(n, x, y, anim) { + let bases = [{baseX: x, baseY: y, baseAngle : 0}]; + for (let i = 0; i < n; i++) { + let newBases = [] + for (let j = 0; j < Math.pow(2, i); j++) { + let sign = isEven(j) ? 1 : -1 + let {baseX, baseY, baseAngle} = bases[Math.floor(j / 2)] + let newAngle = i > 0 ? baseAngle + sign * 18 : 0 + let newX = baseX + 20 * Snap.sin(newAngle) + let newY = baseY - 20 * Snap.cos(newAngle) + paper2.path("").attr(pathStyle).attr({d: `M ${baseX},${baseY} L ${newX},${newY}`}).animate({opacity:1}, 8000, mina.easeout); + newBases.push({baseX:newX, baseY:newY, baseAngle: newAngle}) + } + bases = newBases + }; + + bases.forEach((item) => anim(item.baseX, item.baseY) ) + +}; + +function flowersBloom(x, y) { +let flower = paper2.circle(x, y, 1); +flower.attr({ + fill: "pink", +}).stop().animate({r:5}, 5000, mina.bounce); +}; + +function isEven(n) { + return n % 2 == 0; +}; + +tree(8, 400, 350, flowersBloom); diff --git a/date/main.js b/date/main.js index a44ee82..eced424 100644 --- a/date/main.js +++ b/date/main.js @@ -1,17 +1,96 @@ // year: number function isLeapYear(year) { - //TODO + if (year < 0 || year != year || Number(year) != Number(year) || year == null || year == Infinity || year == -Infinity) { + throw new Error('Invalid value of year'); + } + + return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 } // month: number function monthLength(month) { - //TODO + if (month < 1 || month > 12) { + throw new Error('Invalid value of month'); + } + if ([4, 6, 9, 11].includes(month)) { + return 30 + } + if ([1, 3, 5, 7, 8, 10, 12].includes(month)) { + return 31 + } + if (month == 2) { + return 28 + } +} + +function isNumber(num) { + if (Number(num) != Number(num) || num != num || num < 0 || num == null || num == Infinity || num == -Infinity || num == 0) { + throw new Error('Invalid value of date') + } } // date: string, format dd.MM.YYYY function dayOfWeek(date) { - //TODO - // for inspiration - // https://artofmemory.com/blog/how-to-calculate-the-day-of-the-week-4203.html - // https://wpcalc.com/kak-uznat-den-nedeli-lyuboj-daty/ + + if (!date) { + throw new Error('Invalid value of date') + }; + + let arr = date.split("."); + let dayNumber = Number(arr[0]); + let monthNumber = Number(arr[1]); + let yearNumber = Number(arr[2]); + + isNumber(dayNumber); + isNumber(monthNumber); + isNumber(yearNumber); + if (dayNumber > 31) { + throw new Error('Invalid value of day') + }; + if (monthNumber > 12){ + throw new Error('Invalid value of month') + }; + + let century = Math.floor(yearNumber/100); + let centuryShift; + + if ([3, 7, 11, 15, 19].includes(century)) { + centuryShift = 0 + } + if ([4, 8, 12, 16, 20].includes(century)) { + centuryShift = 6 + } + if ([1, 5, 9, 13, 17, 21].includes(century)) { + centuryShift = 4 + } + if ([2, 6, 10, 14, 18].includes(century)) { + centuryShift = 2 + } + + let decimalYear = (yearNumber % 100); + + let yearShift = ((decimalYear + (decimalYear/4)) % 7); + yearShift = Math.floor (yearShift); + + let monthShifts = [0,3,3,6,1,4,6,2,5,0,3,5]; + let monthShift = monthShifts[monthNumber-1]; + + + let leap = isLeapYear(yearNumber)*([1,2].includes(monthNumber)) + let sumShift = (centuryShift + yearShift + monthShift + dayNumber - leap); + let weekIndex = Math.floor(sumShift % 7); + + let day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + return day[weekIndex]; } + +function getDate(dd,mm,yyyy) {return `${dd}.${mm}.${yyyy}`} + +let yyyy = 1997; +do { + dayOfWeek(getDate(13,7,yyyy)); + if (dayOfWeek(getDate(13,07,yyyy)) == 'Friday') { + alert (yyyy); + }; + yyyy++ +} while (yyyy !== 2117); \ No newline at end of file diff --git a/date/test.js b/date/test.js index 2f8db55..a5d1092 100644 --- a/date/test.js +++ b/date/test.js @@ -1,20 +1,20 @@ describe("is leap year", function() { - it("2020 is leap year", function() { - assert.isTrue(isLeapYear(2020)); - }); + it("2020 is leap year", function() { + assert.isTrue(isLeapYear(2020)); + }); - it("2019 is leap year", function() { - assert.isFalse(isLeapYear(2019)); - }); + it("2019 is leap year", function() { + assert.isFalse(isLeapYear(2019)); + }); - it("1200 is leap year", function() { - assert.isTrue(isLeapYear(1200)); - }); + it("1200 is leap year", function() { + assert.isTrue(isLeapYear(1200)); + }); - it("1000 is not leap year", function() { - assert.isFalse(isLeapYear(1000)); - }); + it("1000 is not leap year", function() { + assert.isFalse(isLeapYear(1000)); + }); describe("throw exception on invalid value", function() { @@ -35,8 +35,8 @@ describe("is leap year", function() { describe("month length", function() { - it(`length of February is 30`, function() { - assert.equal(monthLength(2), 30); + it(`length of February is 28`, function() { + assert.equal(monthLength(2), 28); }); describe("return 30", function() { @@ -45,7 +45,7 @@ describe("month length", function() { function makeTest(x) { it(`length of ${x} is 30`, function() { - assert.equal(monthLength(x), 31); + assert.equal(monthLength(x), 30); }); } @@ -103,32 +103,65 @@ describe("get day of week by date", function() { assert.equal(dayOfWeek('07.05.2016'), 'Saturday'); }); - it(`13.05.2016 is Friday`, function() { + it('13.05.2016 is Friday', function() { assert.equal(dayOfWeek('13.05.2016'), 'Friday'); }); - it(`16.06.1910 is Thursday`, function() { - assert.equal(dayOfWeek('13.05.2016'), 'Thursday'); + it('16.06.1910 is Thursday', function() { + assert.equal(dayOfWeek('16.06.1910'), 'Thursday'); }); - it(`11.10.2006 is Wednesday`, function() { - assert.equal(dayOfWeek('13.05.2016'), 'Wednesday'); + it('11.10.2006 is Wednesday', function() { + assert.equal(dayOfWeek('11.10.2006'), 'Wednesday'); }); - it(`17.09.2019 is Tuesday`, function() { - assert.equal(dayOfWeek('13.05.2016'), 'Tuesday'); + it('17.09.2019 is Tuesday', function() { + assert.equal(dayOfWeek('17.09.2019'), 'Tuesday'); }); - it(`04.01.1999 is Monday`, function() { - assert.equal(dayOfWeek('13.05.2016'), 'Monday'); + it('04.01.1999 is Monday', function() { + assert.equal(dayOfWeek('04.01.1999'), 'Monday'); }); describe("throw exception on invalid value", function() { - let invalidValue = ['12,2.01.1234','12.32.1006','32.2.00','','07.07.-1006','07.07.-1006','12..2.08','0.-.=',' ']; - function makeTest(x) { - it(`${x} throws exception`, function() { - assert.throws(() => dayOfWeek(x), 'Invalid value of month'); - }); + let dateInvalidValue = [''].forEach(x => { + it(`${x} throws exception`, function() { + assert.throws(() => dayOfWeek(x), 'Invalid value of day'); + }); + }); + + for (let i = 0; i < dateInvalidValue.length; i++) { + makeTestForDate(dateInvalidValue[i]); } - for (let i = 0; i < invalidValue.length; i++) { - makeTest(invalidValue[i]); + + let dayInvalidValue = ['12,2.01.1234', '32.2.00', ' ', '0.-.='].forEach(x => { + it(`${x} throws exception`, function() { + assert.throws(() => dayOfWeek(x), 'Invalid value of day'); + }); + }); + + for (let i = 0; i < dayInvalidValue.length; i++) { + makeTestForDay(dayInvalidValue[i]); + } + + + let monthInvalidValue = ['12.32.1006', '12..2.08'].forEach(x => { + it(`${x} throws exception`, function() { + assert.throws(() => dayOfWeek(x), 'Invalid value of month'); + }); + }); + + for (let i = 0; i < monthInvalidValue.length; i++) { + makeTestForMonth(monthInvalidValue[i]); + } + + + + let yearInvalidValue = ['07.07.-1006'].forEach(x => { + it(`${x} throws exception`, function() { + assert.throws(() => dayOfWeek(x), 'Invalid value of year'); + }); + }); + + for (let i = 0; i < yearInvalidValue.length; i++) { + makeTestForYear(yearInvalidValue[i]); } }); diff --git a/loops_and_arrays/main.js b/loops_and_arrays/main.js index e69de29..9a7fb9a 100644 --- a/loops_and_arrays/main.js +++ b/loops_and_arrays/main.js @@ -0,0 +1,90 @@ +// let cardNumber = prompt("Enter your card number please"); +// +// function cardNumberValidation(cardNumber) { +// let cardArray = (cardNumber.split('')).reverse(); +// if (cardArray.length !== 16) { +// throw new Error('Invalid card number'); +// } +// cardArray = cardArray.map(function (it, index) { +// return ((index % 2 !== 0) ? (it * 2) : (+it)) +// }); +// let result = cardArray.reduce((sum, curr) => sum + (Math.floor(curr/10) + curr%10), 0); +// if (result !== result) { +// throw new Error('Invalid card number'); +// } +// return (result % 10 == 0) +// } +// +// if (cardNumberValidation) { +// alert("Card is valid"); +// } else { +// alert ("Card is not valid"); +// } +// cardNumberValidation(cardNumber); + +function factorial(n) { + return (n !== 0) ? n * factorial(n - 1) : 1; +} + +function toradianAngle(degreeAngle) { + return degreeAngle * Math.PI / 180; +} + +function customSin(degreeAngle, precision) { + let i = 0; + let sin = 0; + let e = 0; + do { + e = Math.pow(-1, i) * Math.pow(degreeAngle, 2 * i + 1) / factorial(2 * i + 1); + i++; + sin += e; + } while (Math.abs(e) > precision); + return sin; +} + + +function customCos(degreeAngle, precision) { + let i = 0; + let cos = 0; + let e = 0; + do { + e = ( (Math.pow(-1, i)) * ( (Math.pow(degreeAngle, 2 * i)) / factorial(2 * i) ) ); + i++; + cos += e; + } while (Math.abs(e) > precision); + return cos; +} + + + + +function generateTable(precision, from, to, customTrig, realTrig) { + let table = []; + for (let degreeAngle = from; degreeAngle <= to; degreeAngle +=10) { + let result = {angle: degreeAngle, real: realTrig(toradianAngle(degreeAngle)), calculated: customTrig(toradianAngle(degreeAngle), precision)}; + table.push(result); + } + return table; +} + + + +function printTable(array) { + let row = [(`| angle | real | calculated `)]; + for (let i = 0; i <= array.length; i++) { + let obj = array[i]; + let arrayFromObj = []; + for (let key in obj) { + let value = obj[key]; + let space = ` `; + arrayFromObj.push(`|` + space.repeat(11 - value.toFixed(3).toString().length) + value.toFixed(3) + ` `); + } + row.push(arrayFromObj.join(``)); + } + console.log(row.join(`|\n`)) +} + +let arrayOfSin = generateTable(0.01, 0, 90, customSin, Math.sin); +printTable(arrayOfSin); + + diff --git a/loops_and_arrays/test.js b/loops_and_arrays/test.js index e69de29..055550d 100644 --- a/loops_and_arrays/test.js +++ b/loops_and_arrays/test.js @@ -0,0 +1,30 @@ +describe("Card number validation", function() { + + it("4242424242424242 is valid card number", function() { + assert.isTrue(cardNumberValidation('4242424242424242')); + }); + + it("5168755450326695 is valid card number", function() { + assert.isTrue(cardNumberValidation('5168755450326695')); + }); + + it("1111111111111111 is not valid card number", function() { + assert.isFalse(cardNumberValidation('1111111111111111')); + }); + + describe("throw exception on invalid value", function() { + + let invalidValue = ['2345678909876543456789', 'qwertyuiopjjasdf', '']; + + function makeTest(x) { + it(`${x} throws exception`, function() { + assert.throws(() => cardNumberValidation(x), 'Invalid card number'); + }); + } + + for (let i = 0; i < invalidValue.length; i++) { + makeTest(invalidValue[i]); + } + + }); +}); diff --git a/snap_svg/main.css b/snap_svg/main.css index 0ccd601..78ec659 100644 --- a/snap_svg/main.css +++ b/snap_svg/main.css @@ -1,4 +1,5 @@ svg { border: 1px solid black; cursor: pointer; -} \ No newline at end of file + background-color: '#E289B3' +}; diff --git a/snap_svg/main.js b/snap_svg/main.js index 3cd2224..6d6153f 100644 --- a/snap_svg/main.js +++ b/snap_svg/main.js @@ -1,9 +1,9 @@ "use strict"; let style = { - fill: '#387', - stroke: '#222', - strokeWidth: 5 + fill: '#D20F0F', + stroke: '#FF4400', + strokeWidth: 2, }; let paper = Snap(800, 400) @@ -23,6 +23,8 @@ let updatePath = function() { }) } +let rec = paper.rect(0, 0, 20, 20).attr(style).drag() + let move = function(dx, dy, xpos, ypos) { var radius = this.getBBox().r0; if (xpos <= 800 - radius && ypos <= 400 - radius && xpos > radius && ypos > radius) { @@ -36,16 +38,17 @@ let move = function(dx, dy, xpos, ypos) { console.log("Borders are reached") } -paper.click( e => { +paper.click(function(e) { if (e.target.tagName == 'svg' || e.target.tagName == 'path') { paper.circle(e.offsetX, e.offsetY, 15) .attr(style) - .mouseover(function(){ this.stop().animate({r:25}, 500, mina.elastic()) }) - .mouseout(function(){ this.stop().animate({r:15}, 300, mina.easeinout()) }) + .mouseover(function(){ this.stop().animate({r:25}, 600, mina.bounce) }) + .mouseout(function(){ this.stop().animate({r:15}, 400, mina.backin) }) .data("i", pathArray.length) - .drag(move, - () => path.stop().animate({opacity: .2}, 200, mina.easeinout()), - () => path.stop().animate({opacity: 1}, 500, mina.easeinout())) + .drag( + move, + () => path.stop().animate({opacity: .2}, 200, mina.easeinout), + () => path.stop().animate({opacity: 1}, 500, mina.easeinout)) pathArray.push({ x : e.offsetX, @@ -54,4 +57,6 @@ paper.click( e => { updatePath() } -}) \ No newline at end of file +}); + +