From c2a5e544686c507671b3db79dfabb3a0d4a069d8 Mon Sep 17 00:00:00 2001 From: azizck Date: Sun, 22 Sep 2019 11:52:03 -0400 Subject: [PATCH 1/4] done --- README.md | 66 +++++++++- chatbot_style.css | 102 ++++++++-------- debug.log | 305 ++++++++++++++++++++++++++++++++++++++++++++++ index.html | 2 +- js/debug.log | 61 ++++++++++ js/main.js | 75 ++++++++++++ style.css | 52 ++++++++ 7 files changed, 607 insertions(+), 56 deletions(-) create mode 100644 debug.log create mode 100644 js/debug.log create mode 100644 js/main.js create mode 100644 style.css diff --git a/README.md b/README.md index 5e9e1fd..29da157 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,65 @@ -# Chatbot +# Week8 - Chatbot -Please see the instructions [here](https://docs.google.com/document/d/1BP27Tjgit66o6kLpzu8RMnPr7M5GWpC_2N05DvMMTUE/). +See the instructions [here](https://docs.google.com/document/d/1123vh08osRkCyqsnyR0SQMC1n4l0DlDIS0OYSrPSlY0/edit?usp=sharing) for the first part of your chatbot, or read below: + +**Due Date: Sunday, September 15 at 6:00 p.m.** + +Complete the following assignment and create a pull request to GitHub for reviewing by the instructor. + +The homework assignments for the next few lectures will be interconnected. By the end of JavaScript 2, you will have developed a fully functional chatbot. These assignments will build on the previous week's assignment, therefore, it is very important that you complete the assignment in a timely manner (i.e. by the due date). + +## CHATBOT PART I + +In this first assignment, you will begin by building a very simple chatbot. As you progress through the remaining JavaScript weeks, you will add more and more functionality to the chatbot. + +You are provided the HTML and CSS code for this assignment in this repository. Your task will be to write the JavaScript portion to make the chatbot functional and interactive. Remember to add comments to your code, describing what it does. + +1. In your JavaScript code, declare a variable and initialize it as an object. +2. Add two properties to the object: ‘input’ and ‘output’. + 1. To the ‘input’ property/key assign a greeting or a question that you want the chatbot to reply to. Some examples are: + * Hello + * How are you? + * What is your favourite colour? + 2. To the ‘output’ property/key assign answers to the greetings or questions you wrote in part a. Some examples to the inputs above are: + * Hi + * Great! + * I have so many favorites it's hard to choose one. +3. console.log() your variable to confirm that you have assigned the values correctly. If done correctly, you output should look similar to: +```js +{ input: 'input1', output: 'output1' } +``` + +4. Below your variable declaration, create a function called ‘reply’. +5. In the ‘reply’ function, declare a variable called ‘question’ and assign to it the **value**of the HTML `` element. + - HINT: use the id assigned to the `` element to get access to the element. +6. Use a conditional statement to check if the value you stored in the 'question' variable matches the 'input' defined in the object you first created. + 1. If it does, assign the corresponding output to the **value** of the -
- +
+ + +
+ + + - \ No newline at end of file diff --git a/js/debug.log b/js/debug.log deleted file mode 100644 index a0df5ae..0000000 --- a/js/debug.log +++ /dev/null @@ -1,61 +0,0 @@ -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.158:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.159:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report -[0917/191312.160:ERROR:crash_report_database_win.cc(469)] failed to stat report diff --git a/js/main.js b/js/main.js index aac3784..8c4093f 100644 --- a/js/main.js +++ b/js/main.js @@ -1,75 +1,244 @@ -/* -Aziz Omar -Chatbot2 -*/ -// contains all inputs and outputs let data = [{ - input: 'Hi', - output: ['Hello', 'Hey !', 'Whats up?'] - }, - - { - input: 'How are you?', - output: ['good', 'not bad', 'doing well'] - }, - - { - input: 'What is your favourite color?', - output: ['red', 'gray', 'black'] - }, - - { - input: 'Where are you', - output: ['home', 'at work', 'on vacation'] - } + input: ['hi', 'hey!', 'yo yo'], + output: ['Hello', 'Hey !', 'Whats up?'] + }, + { + input: ['how are you?', 'how is it going?', 'how are you doing?'], + output: ['good', 'not bad', 'doing well'] + }, + + { + input: ['what is your favourite color?', 'what color do you prefer?', 'tell me what color you like?'], + output: ['red', 'gray', 'black'] + }, + + { + input: ['where are you', 'are you near by', 'where are you located'], + output: ['home', 'at work', 'on vacation'] + }, + { + input: ['show me a dog', 'can you display a dog ? ', 'do you have photos of dogs? '], + output: [displayAdog] + }, + { + input: ['show me the weather', 'what is the weather like today?', 'what is the temperature?'], + output: [getWeather] + } ]; +const findSimillarQuestion = givenInput => (item) => { + return item.input.includes(givenInput); +} + +const reply = () => { + let bot; + let question = document.getElementById("input").value; + let output = document.getElementById("output"); + let img = document.getElementById("img"); + question = question.toLowerCase(); + let rndmNumber = Math.floor(Math.random() * data[0].output.length); + let detectedQuestion = data.filter(findSimillarQuestion(question))[0]; + //console.log(detectedQuestion); + if (detectedQuestion) { + temp = detectedQuestion; + if (typeof detectedQuestion.output[0] == "string") { + bot = detectedQuestion.output[rndmNumber]; + img.style.display = 'none'; + } else { + bot = "ok"; + detectedQuestion.output[0](); + } + } else { + img.style.display = 'none'; + bot = " I was not programmed to understand this command "; + } + output.textContent = bot; +} // end of reply + + +document.getElementById("say").addEventListener("click", reply); + +//diplay an image of a dog +function displayAdog() { + var xhttp = new XMLHttpRequest(); + xhttp.open("GET", "https://dog.ceo/api/breeds/image/random", true); + xhttp.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + let img = document.getElementById("img"); + img.style.display = 'block'; + img.src = (JSON.parse(this.responseText)).message; + } + } + xhttp.send(); + +} + + +// get longitude and latitude of user, using their location +function getCoordinates() { + return new Promise(function (resolve, reject) { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(showPosition, function () { + reject(Error('user did not give permission to use their location')); + }); + } else { + console.log("Geolocation is not supported by this browser."); + } + + function showPosition(position) { + lat = position.coords.latitude; + lon = position.coords.longitude; + resolve({ + 'lat': lat, + 'lon': lon + }); + + } + + }); + +} + + + + +// make an xmlHtppRequest +function makeRequest(method, url) { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open(method, url); + xhr.onload = function () { + if (this.status >= 200 && this.status < 300) { + resolve(xhr.response); + } else { + reject({ + status: this.status, + statusText: xhr.statusText + }); + } + }; + + xhr.onerror = function () { + reject({ + status: this.status, + statusText: xhr.statusText + }); + + }; + xhr.send(); + }); +} + /* -iterates through an array to find a question simillar to user's input + */ +async function getWeather() { + try { + //coo + let coordinates = await getCoordinates().catch(e => console.log('Error: ', e.message)); + let lat = coordinates.lat; + let lon = coordinates.lon; + let url = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=e80c522abcec7f0f2549264809902922`; + let response = await makeRequest("GET", url); + + response = JSON.parse(response); + let temp = (response.main.temp - 273).toFixed(0); + let cloud = response.weather[0].description; + let city = response.name; + + let output = document.getElementById("output"); + //assign the weather to output + output.textContent = `Temprature: ${temp} C | cloud: ${cloud} | in ${city}`; + } catch (err) { + console.log("err" + err); + console.log("err" + err.status); + } + -const findSimillarQuestion = givenInput => (item) => { - // return item.input.toUpperCase().includes(givenInput.toUpperCase()); - return item.input.toUpperCase() == givenInput.toUpperCase(); } -// repaly function -const replay = () => { - let question = document.getElementById("input").value; - let txtArea = document.getElementById("output"); - let rndmNumber = Math.floor(Math.random() * data[0].output.length); - let detectedQuestion = data.filter(findSimillarQuestion(question))[0]; - if (detectedQuestion) { - let maxAnswer=detectedQuestion.output.sort()[detectedQuestion.output.length-1]; - let minAnswer=detectedQuestion.output.sort()[0] - //assign the longest answer to maxAnswer - /* - detectedQuestion.output.filter(item => { - if (item.length > maxAnswer.length) maxAnswer = item; - }); - */ - //assign the shortest answer to minAnswer - /*detectedQuestion.output.filter(item => { - if (item.length < minAnswer.length) minAnswer = item; - }); - */ - if (document.getElementById('shortest').checked) - txtArea.innerHTML = minAnswer; - else if (document.getElementById('longest').checked) - txtArea.innerHTML = maxAnswer; - else - txtArea.innerHTML = detectedQuestion.output[rndmNumber]; +// concatenate all questions into a single array +let inputsData = []; +data.forEach(function (item) { + inputsData = inputsData.concat(item.input) +}); + + +/* + Takes an array of strings, a callback function, and a string + pass each item of the given array, and the given string to the callback function + store the returned value from the callback in an array and returns it +*/ +function compare(arr, callBack, question) { + let records = []; + arr.forEach(function (item, index) { + records.push(callBack(item, question)); + }); + return records; +}; + + + + + +/* + Takes two strings compares their chars, and return the number of first simillar chars +*/ +function compareChars(str1, str2) { + let counter = 0; + for (let i = 0; i < str1.length; i++) { + if (str1[i] === str2[i]) { + counter++; + } else { + break; + } + } + return counter; +} + + +let input = document.getElementById("input"); +let placeHolder = document.getElementsByClassName("placeholder")[0]; +let arrowIcon = document.getElementById("arrow"); + +// input on typing +input.addEventListener("input", function () { + // array contains number of simillar chars comparing to each input question + let comparedInputs = compare(inputsData, compareChars, input.value); + + // item with largest value is closest to the users question + let maxItem = Math.max(...comparedInputs); + + // get the index of the largest Item + let index = comparedInputs.indexOf(maxItem) + + // get the most similar question from the data + let similarQuestion = inputsData[index]; + + // assign the most similar question to user's input to place holder + placeHolder.attributes["data-placeholder"].value = similarQuestion; + +}); + - } else - txtArea.innerHTML = "I do not understand that command"; +/// arrow symbol on click replaces input text with its place holder +input.addEventListener('keydown', function (event) { + if (event.key == "ArrowRight") { + // assign place holder value to input value + input.value = placeHolder.attributes["data-placeholder"].value; + } +}); -} // end of replay +/// arrow icon on click replaces input text with its placeholder +arrowIcon.addEventListener('click', function (event) { + // assign place holder value to input value + input.value = placeHolder.attributes["data-placeholder"].value; -document.getElementById("submit").addEventListener('click', replay); \ No newline at end of file +}); \ No newline at end of file diff --git a/style.css b/style.css deleted file mode 100644 index b4c8731..0000000 --- a/style.css +++ /dev/null @@ -1,52 +0,0 @@ -button { - font-family: Helvetica; - font-size: 10pt; - width: 92px; -} - -textarea { - font-family: arial; - font-size: 10pt; -} - -body { - color: #333; - background-color: #efefef; - font: 13px helvetica, arial, freesans, clean, sans-serif; -} - -#demo { - width: 80%; - max-width: 1000px; - margin-left: auto; - margin-right: auto; - padding: 20px; - background-color: #F8F8F8; - border: 1px solid #ccc; - box-shadow: 0 0 10px #999; - line-height: 1.4em; - font: 13px helvetica, arial, freesans, clean, sans-serif; - color: black; -} - -#demo input { - padding: 8px; - font-size: 14px; - border: 1px solid #ddd; - width: 400px; -} - -#demo textarea { - padding: 8px; - font-size: 14px; - border: 1px solid #ddd; - width: 800px; -} - -input:focus { - outline: none; -} - -textarea:focus { - outline: none; -} \ No newline at end of file From b9988ba1eaaf57b909021aa9a3a5d575f97053c0 Mon Sep 17 00:00:00 2001 From: azizck Date: Mon, 14 Oct 2019 13:03:50 -0400 Subject: [PATCH 3/4] handled the case of a user not giving the permission to use their location --- js/main.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/js/main.js b/js/main.js index 8c4093f..5fc1070 100644 --- a/js/main.js +++ b/js/main.js @@ -135,10 +135,25 @@ function makeRequest(method, url) { */ async function getWeather() { try { - //coo - let coordinates = await getCoordinates().catch(e => console.log('Error: ', e.message)); + let userCoordinates; + let coordinates; + userCoordinates = await getCoordinates().catch(e => { + coordinates = { + "lat": 0, + "lon": 0 + }; + console.log('Error: ', e.message) alert(e.message); + }); + + + if (!coordinates) { + coordinates = userCoordinates; + } + + let lat = coordinates.lat; let lon = coordinates.lon; + let url = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=e80c522abcec7f0f2549264809902922`; let response = await makeRequest("GET", url); From df4616fd845b5000187021d8958f0046a84131da Mon Sep 17 00:00:00 2001 From: azizck Date: Mon, 14 Oct 2019 13:05:42 -0400 Subject: [PATCH 4/4] handled the case of a user not giving the permission to use their location --- js/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index 5fc1070..6e74673 100644 --- a/js/main.js +++ b/js/main.js @@ -142,7 +142,8 @@ async function getWeather() { "lat": 0, "lon": 0 }; - console.log('Error: ', e.message) alert(e.message); + console.log('Error: ', e.message) + alert(e.message); });