How do I randomise multiple groups in a loop? - javascript

I am making a little test that people can use to check their knowledge of hiragana.
It randomly selects 4 hiragana from a 2nd array and one correct spelling of the hiragana.
It looks pretty much exactly as it should with one twist. The correct answer is in the same place every time! The second hiragana always shows as correct. This is the code that I have used to randomise. Thanks in advance for your help!
var first = Math.floor((Math.random() * 46));
var second = Math.floor((Math.random() * 46));
var third = Math.floor((Math.random() * 46));
var fourth = Math.floor((Math.random() * 46));
var selector = Math.floor((Math.random() * 4));
var firstHiragana = hiraganaSet[first][0];
var secondHiragana = hiraganaSet[second][0];
var thirdHiragana = hiraganaSet[third][0];
var fourthHiragana = hiraganaSet[fourth][0];
alert(selector)
if (selector = 0){
var romaji = hiraganaSet[first][1];
var romajiData = hiraganaSet[first][0];
}
else if (selector = 1){
var romaji = hiraganaSet[second][1];
var romajiData = hiraganaSet[second][0];
}
else if (selector = 2){
var romaji = hiraganaSet[third][1];
var romajiData = hiraganaSet[third][0];
}
else if (selector = 3){
var romaji = hiraganaSet[fourth][1];
var romajiData = hiraganaSet[fourth][0];
}
http://jsfiddle.net/jB6cp/1/

Most likely because you're assigning values rather than doing a comparison check:
if (selector = 0)
should be
if (selector == 0)
or
if (selector === 0)
depending on how strict you want your check to be.
= assigns the value to the variable.
== does a comparison for value only.
=== does a comparison for value and type.
There's some more information here.

Related

How to modify data-list element or alternative

I am working on an autocomplete text input by testing for string similarity, rather than checking for perfect character matches. This way, a dropdown like a datalists would still present the user with suggestions even if they accidentally add an extra character or spell their desired input wrong.
I have a working Javascript file that can compare the string input from an HTML text input to all the strings in a JSON file that holds about 700 school names as strings. The Javascript file then formats the HTML and passes the 10 most similar strings into an unordered list(for debugging) and into a data-list (where the user will be able to pick their correct answer).
However, datalists seem to have built-in autocomplete that check for identical groups of characters and the datalists will intelligently remove suggestions if the inputted string does not exist within the suggestion.
<input
type ="text"
id="search"
list="hsDropdown"
class ="form-control form-control-lg"
placeholder="High School Name"
autocomplete="off"
autofocus = "false"
/>
<hr/>
<p id="word"></p>
<datalist id ="hsDropdown"></datalist>
<ul id ="list"></ul>
</main>
<script src="js/script.js" type ="text/javascript"></script>
<script src="js/ukkonen/index.js" type ="text/javascript"></script>
The options within the datalist in my HTML are properly populated by my script.js with the most similar strings, but I need to find a way to override the property of the datalist tag that causes results with nonperfect matches to not appear, or
I would need to find an alternative way to make a dropdown list appear from a textbox that is not limited to hard auto-correct.
You could look at the select2 jQuery plugin and the Fuzzy search issue opened there
As per requestor, he has implemented the fuzzy_match function and embedded it into the plugin as the following:
I've also a function called matcher, which looks something like:
function matcher(term, text){
if(term.term === undefined){
return {text: text, score: 1};
}
var match = fuzzy_match(term.term, text.text);
return (match[0])?{text: text, score: match[1]}:false;
}
I also have a sorter, which sorts the matched elements, (so matching elements come at top)
function sorter(data) {
return data.filter(function(item) {
return !!item;
}).sort((a, b) => b.score - a.score)
.map(item => item.text);
}
And whenever we're invoking a select2 on a element, we're passing this matcher as a matcher option, and sorter as sorter option, which looks something like:
$("#element").select2({
placeholder: 'select a name',
matcher,
sorter
})
Here is the fuzzy_match function code provided:
/**
*
* #param pattern
* #param str
* #returns {[boolean,score,formatted]}
*/
function fuzzy_match(pattern, str) {
// Score consts
var adjacency_bonus = 55; // bonus for adjacent matches
var separator_bonus = 10; // bonus if match occurs after a separator
var camel_bonus = 10; // bonus if match is uppercase and prev is lower
var leading_letter_penalty = -3; // penalty applied for every letter in str before the first match
var max_leading_letter_penalty = -9; // maximum penalty for leading letters
var unmatched_letter_penalty = -1; // penalty for every letter that doesn't matter
// Loop variables
var score = 0;
var patternIdx = 0;
var patternLength = pattern.length;
var strIdx = 0;
var strLength = str.length;
var prevMatched = false;
var prevLower = false;
var prevSeparator = true; // true so if first letter match gets separator bonus
// Use "best" matched letter if multiple string letters match the pattern
var bestLetter = null;
var bestLower = null;
var bestLetterIdx = null;
var bestLetterScore = 0;
var matchedIndices = [];
// Loop over strings
while (strIdx != strLength) {
var patternChar = patternIdx != patternLength ? pattern.charAt(patternIdx) : null;
var strChar = str.charAt(strIdx);
var patternLower = patternChar != null ? patternChar.toLowerCase() : null;
var strLower = strChar.toLowerCase();
var strUpper = strChar.toUpperCase();
var nextMatch = patternChar && patternLower == strLower;
var rematch = bestLetter && bestLower == strLower;
var advanced = nextMatch && bestLetter;
var patternRepeat = bestLetter && patternChar && bestLower == patternLower;
if (advanced || patternRepeat) {
score += bestLetterScore;
matchedIndices.push(bestLetterIdx);
bestLetter = null;
bestLower = null;
bestLetterIdx = null;
bestLetterScore = 0;
}
if (nextMatch || rematch) {
var newScore = 0;
// Apply penalty for each letter before the first pattern match
// Note: std::max because penalties are negative values. So max is smallest penalty.
if (patternIdx == 0) {
var penalty = Math.max(strIdx * leading_letter_penalty, max_leading_letter_penalty);
score += penalty;
}
// Apply bonus for consecutive bonuses
if (prevMatched)
newScore += adjacency_bonus;
// Apply bonus for matches after a separator
if (prevSeparator)
newScore += separator_bonus;
// Apply bonus across camel case boundaries. Includes "clever" isLetter check.
if (prevLower && strChar == strUpper && strLower != strUpper)
newScore += camel_bonus;
// Update patter index IFF the next pattern letter was matched
if (nextMatch)
++patternIdx;
// Update best letter in str which may be for a "next" letter or a "rematch"
if (newScore >= bestLetterScore) {
// Apply penalty for now skipped letter
if (bestLetter != null)
score += unmatched_letter_penalty;
bestLetter = strChar;
bestLower = bestLetter.toLowerCase();
bestLetterIdx = strIdx;
bestLetterScore = newScore;
}
prevMatched = true;
}
else {
// Append unmatch characters
formattedStr += strChar;
score += unmatched_letter_penalty;
prevMatched = false;
}
// Includes "clever" isLetter check.
prevLower = strChar == strLower && strLower != strUpper;
prevSeparator = strChar == '_' || strChar == ' ';
++strIdx;
}
// Apply score for last match
if (bestLetter) {
score += bestLetterScore;
matchedIndices.push(bestLetterIdx);
}
// Finish out formatted string after last pattern matched
// Build formated string based on matched letters
var formattedStr = "";
var lastIdx = 0;
for (var i = 0; i < matchedIndices.length; ++i) {
var idx = matchedIndices[i];
formattedStr += str.substr(lastIdx, idx - lastIdx) + "<b>" + str.charAt(idx) + "</b>";
lastIdx = idx + 1;
}
formattedStr += str.substr(lastIdx, str.length - lastIdx);
var matched = patternIdx == patternLength;
return [matched, score, formattedStr];
}

How to make if statement keep working after clicking on a button once

I will try to explain it better. I rewrote a code, to make it better as an example. As you can see I have an app to generate a number, but to generate correct number I have to click 5-15 times on a button, due to random and if statement. I want to ask how to make a process to skip incorrect numbers and give an actual answers ( which took 5-15 clicks ) only in one click. I can give more information, if you didn't understand me. Thank you very much!
*video: https://vimeo.com/251109159
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
var ans = "you are right!";
var newNumber = firstNum + ranNumb;
if ( newNumber % 5 == 0){
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}
}
You can wrap the generation of your number inside a do while loop:
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ans = "you are right!";
var newNumber;
do {
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
newNumber = firstNum + ranNumb;
} while (newNumber % 5 !== 0);
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}
Instead of generating a random integer in [0, 100) and checking to see if it's a multiple of 5, generate a random integer in [0, 20) and multiply it by 5. That guarantees that your result will be a multiple of 5 between 0 and 100.
var ranNumb = Math.floor(Math.random() * 20) * 5;
hope this might help. You have to use if-else rather then if conditional statement
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
var ans = "you are right!";
var newNumber = firstNum + ranNumb;
if ( newNumber % 5 == 0){
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}else{
document.getElementById("newnumber").innerHTML = "You are wrong";
}
}

How can I store looped data into an array?

I want to store all the looped data into the Course_Code and Grade arrays.
Everything works except that only the last entered value is stored. What must I do to save all the data in the array?
const MIN = 999;
const MAX = 10000;
const minLet = 64;
const maxLet = 91;
const GRADE_VALUE = 'parseInt(7)%parseInt(6)%parseInt(5)%parseInt(4)%parseInt(3)%parseFloat(1.5)';
var i;
var j;
var Grade = new Array();
var Course_Code = new Array();
while (willingnes != false) {
var willingnes = confirm('Do you want to enter new Course Code? Click OK to continue or Cancel to stop?');
if (willingnes == true) {
Course_Code = prompt('Enter your Course Code', 'AAA1000');
var Digits = parseInt(Course_Code.slice(-4)); // extract the last four digits from course code
while (Course_Code.charCodeAt(0) < minLet || Course_Code.charCodeAt(0) > maxLet || Course_Code.charCodeAt(1) < minLet || Course_Code.charCodeAt(1) > maxLet || Course_Code.charCodeAt(2) < minLet || Course_Code.charCodeAt(2) > maxLet || isNaN(Digits) || Digits < MIN || Digits > MAX) {
alert('Your input was invalid');
Course_Code = prompt('Enter your Course Code', 'AAA1000');
}
Grade = prompt('Input a valid Course grade:');
while (GRADE_VALUE.indexOf(Grade) < 0) {
alert('Invalid Course value.');
Grade = prompt('Re-enter valid course grade:');
}
}
}
alert(Course_Code);
alert(Grade);
Instead of assigning your array variables, you should use the push function to add the content.
Perhaps this would give you a better understanding of arrays:
https://www.w3schools.com/js/js_arrays.asp
This is how you assign a code to an array:
First you check the value and then you add it to the array by pushing it.
What you were doing was just assigning a new value each time.
var code = prompt('Enter your Course Code', 'AAA1000');
if (code) {
Course_Code.push(code);
}
for more info see here: https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Array/push

jQuery - Simple math returning NaN

I am trying to do some simple math, using below function. The function is called onChange:
var exposure = $('#exposure').find(":selected").val();
var budget = $('.budget').val();
var ppc = $('.ppc').val();
var value = budget/ppc;
var total2 = Math.floor(value*0.95);
if(exposure == 2){
var dref = 0.0005;
}else if(exposure == 3){
var dref = 0.005;
}else if(exposure == 4){
var dref = 0.001;
}
if(exposure > 1){
var add = dref+ppc;
var value2 = budget/add;
var total2 = Math.floor(value2*0.95);
}
$("#sum").text("" + total2 + " Clicks");
My problem is, that if exposure > 1, the total2 value in #sum will return NaN
What am I doing wrong?
Do a parseInt(value,10) for intergers or parseFloat(value) for float.
JavaScript appends the values if the data type is not a number.
Like:
budget = parseInt(budget,10);
You got to use parseInt or parseFloat. I would say parseFloat something like,
var budget = parseFloat($('.budget').val());
var ppc = parseFloat($('.ppc').val());
var value = parseFloat(budget/ppc);
var total2 = parseFloat((value*0.95));

javascript - Get a portion of the cookie value with substr method

I have a cookie called "login" that contains a structure like "username|hashcode|salt".
Here's my code:
function readTheCookie(the_info)
{
var the_cookie = document.cookie;
var the_cookie = unescape(the_cookie);
var broken_cookie2 = the_cookie.substr(6);
alert(broken_cookie2);
}
readTheCookie('login');
I'ts giving me
pickup22|d47f45d141bf4ecc999ec4c083e28cf7|4ece9bce292e1
Now I just want the first part (everything before the first pipe , in that case, I want pickup22)
How can I do that? Cause the username will never be the same, so I cant put a "fixed" lenght.
Any help appreciated!
var readTheCookie = function (the_info) {
var the_cookie = document.cookie.split(";"), a = the_cookie.length, b;
for (b = 0; b < a; b += 1) {
if (the_cookie[b].substr(0, the_info.length) === the_info) {
return the_cookie.split("=")[1].split("|")[0];
}
}
if (b === a) {
return "";
}
},
username = readTheCookie('login');
That is nice and compact, plus easy to read, and finally it is JSLint compliant. Enjoy!
best way is to use split() method.
var parts = new Array();
parts = broken_cookie2.split("|");
var username = parts[0];
var hashcode = parts[1];
var salt = parts[2];

Categories