JavaScript in HTML code: Random numbers are not evenly distributed - javascript

I've got the following problem:
I'm uploading a survey on amazon mturk using Python and the survey is done via HTML and javascript. I show one of three different versions of the survey to participants, which I select by generating a random number via javascript. I store the number in local storage to prevent refreshing the website from resetting it. The problem I find is that more people seem to get versions 1 than version 3. But I cannot recreate the problem for myself when running the code in Tryit Editor online.
Could you please help me understand (and fix) why this happens? The following is the (trimmed) HTML code that I upload. I replaced text and removed fluff.
<HTMLQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd">
<HTMLContent><![CDATA[
<!-- YOUR HTML BEGINS -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<script type='text/javascript' src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js'></script>
<script>
function test(){
document.getElementById('txt-field').value = "1";
}
</script>
</head>
<body>
<form name='mturk_form' method='post' id='mturk_form' action='https://www.mturk.com/mturk/externalSubmit'><input type='hidden' value='' name='assignmentId' id='assignmentId'/>
<span>
<INPUT TYPE="text" NAME="link_click" id='txt-field' value="0" style="display: none">
<div><h3><a href="www.google.com" target="_blank" id='report420' onclick="test()" >link</a></h3>
Instructions</div>
<div><table border="1" style="height: 258px;" width="196"><tbody>Table</tbody></table></div>
</span>
<!--I think the relevant part starts here-->
<script>
document.write("Miscellaneous question");
var i = localStorage.getItem('i') || Math.floor(3*Math.random());
localStorage.setItem('i',i);
if (i==0){
document.write("Version 1");
}
if (i==1){
document.write("Version 2");
}
if (i==2){
document.write("Version 3");
}
document.write("Miscellaneous question");
</script>
<p><input type='submit' id='submitButton' value='Submit' /></p></form>
<script language='Javascript'>turkSetAssignmentID();</script>
</body></html>
<!-- YOUR HTML ENDS -->
]]>
</HTMLContent>
<FrameHeight>600</FrameHeight>
</HTMLQuestion>

The random function Math.floor(3*Math.random()) has uniform distribution, but I don't think that 400 samples are enough so that you can see it in action (as #desoares mentioned).
Testing code:
var count = [0, 0, 0];
var n = 1000000;
document.write('Testing for ' + n + ' samples : ');
for (var i = 0; i < n; i++) {
count[Math.floor(3*Math.random())]++;
}
document.write(JSON.stringify(count));
var count = [0, 0, 0];
var n = 400;
document.write('Testing for ' + n + ' samples : ');
for (var i = 0; i < n; i++) {
count[Math.floor(3*Math.random())]++;
}
document.write(JSON.stringify(count));
Also, if you want to be sure that people from the same computer are not forced to take the same version, you should clear the saved variable localStorage.removeItem('i'); on submit. You may also add an expiration mechanic.

Related

Getting Array positions in HTML automatically

I have many arrays some upto 60 some upto 100. I am trying to get the text at the 0 position of this arrays for all arrays. I am sorry I don't know how to frame the question correctly. I don't want to type (greeting[0])[1] etc for say 100 times for every greeting. This is my code so far. Can someone help me in this! The greeting[0] etc actually go till 60 etc. Is it possible to do something like let i = 0 , for greeting.length , if i < greeting.length , i++ , and somehow put (greeting[i][0]}. And the result will be such that it show the values of all greeting shows in the paragraph element or in a separate window or something. I am still new to HTML so forgive me is if this seems basic.
Edited Question Update.
P.S. Some of my Arrays have the format greeting[0] = new Greet["Hola", "Salve", "Olá"] . I had to do it such because I use the three options. Is there any way I can automate the process with this?
Edited Question - Update 1
So I have updated the code to be more representative of what I am trying to ask. Basically here I want to provide a button so that on clicking the button I can see all the English words I can choose from. So I want to do something like get the value of the English words in greeting 0, 1 etc and display them separately so that we can select which English word we want instead of just numbers which we don't know what word they represent. Can someone help me with this please!
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p id="English"> Select English Word </p>
<p id="French"> Click below button </p>
<p id="Italian"> Click below button </p>
<button onclick="Another()"> CLick </button>
<script type="text/javascript" src="./script.js"></script>
</body>
</html>
var greeting = [];
greeting[0] = new Word("Hi", "salut", "Ciao") ;
greeting[1] = new Word("Hello", "Salve", "Ciao") ;
greeting[2] = new Word("Welcome", "Bienvenue", "benvenuta") ;
greeting[3] = new Word("Good Day", "Bonne journée", "Buona giornata") ;
greeting[4] = new Word("Good Day", "Bonjour", "Buongiorno") ;
function Word(English,French,Italian) {
this.English = English ;
this.French = French ;
this.Italian = Italian ;
} ;
function Another() {
var nums = window.prompt("Select a number within " + greeting.length ) ;
var optionuser = greeting[nums] ;
var selection = alert("You selected English word " + optionuser.English )
document.getElementById("English").innerHTML = optionuser.English ;
document.getElementById("French").innerHTML = optionuser.French ;
document.getElementById("Italian").innerHTML = optionuser.Italian ;
}
I recommend using Array.map(callback) (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
document.getElementById('something').innerHTML = greeting.map(item=>item[0]).join("<br>");
I have given a slightly modified code below.Hope this is what you are looking for. Since you are new, one advise is not to use window.prompt in your code. Explore some other way. Also change the function Word to Class Word. I think you were trying to create a Class but have given wrong keyword. Instead of prompt, I have used radio button.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Select Language:</p>
<input type="radio" id="English" name="language" value="English">
<label for="English">English</label><br>
<input type="radio" id="French" name="language" value="French">
<label for="French">French</label><br>
<input type="radio" id="Italian" name="language" value="Italian">
<label for="Italian">Italian</label><br>
<input type="radio" id="Spanish" name="language" value="Spanish">
<label for="Spanish">Spanish</label><br>
<button onclick="Another()">Click</button>
<p id="msg"></p>
<script>
class Word {
constructor(English,French,Italian){
this.English = English ;
this.French = French ;
this.Italian = Italian ;
}
} ;
var greeting = [];
greeting[0] = new Word("Hi", "salut", "Ciao") ;
greeting[1] = new Word("Hello", "Salve", "Ciao") ;
greeting[2] = new Word("Welcome", "Bienvenue", "benvenuta") ;
greeting[3] = new Word("Good Day", "Bonne journée", "Buona giornata") ;
function Another() {
let optionSelected = document.querySelector('input[name="language"]:checked').value;
document.getElementById('msg').innerHTML += 'You selected:'+optionSelected;
for(let i=0;i<greeting.length;i++){
document.getElementById('msg').innerHTML += '<br>' + greeting[i][optionSelected];
}
}
</script>
</body>
</html>
Note: Use separate .js file as you did. For answering purpose i have used inline style.

Why isn't this JavaScript code executing?

Sorry, I'm a student and I can't figure out what is wrong with my code! When I click the buttons absolutely nothing happens. I've tried isolating each function and still nothing happens. I've been looking it over for ages trying to find a missing tag or a missing bracket or parentheses or something but I'm not finding it. It's meant to create a mini-blog simulation. You should be able to add an entry to the top of the list with the first function, and you should be able to delete an entry of your choice with the second function. Thank you for any help!
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chapter 5 Activity</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Awesome NBA Blog! Each day, a sentence about the feats of a different legend!</h1>
<ol id="playerEntries">
<li>Michael Jordan: 6 Championship rings in 6 NBA Finals appearances.</li>
<li>Bill Russell: 11 time champion in a 13 year career, including one as a player/head coach.</li>
<li>Kobe Bryant: 5 Championships, 18-time All-Star.</li>
<li>Lebron James: Won a Championship and was the Finals MVP with 3 different teams.</li>
</ol>
<form action="">
Add a new entry:
<input type="text" name="newEntry" id="newEntrySpot" size="80">
<input type="submit" value="Submit" onclick="addEntry()"><br>
Delete an entry(which entry would you like to delete?)
<input type="number" name="entryNum" id="numToDelete">
<input type="button" value="Delete" onclick="deleteEntry()"><br>
</form>
<script type="text/javascript">
function addEntry() {
var newEntry = document.getElementById("newEntrySpot").value;
var newestEntry = document.createElement("li");
newestEntry.innerHTML = newEntry;
var blogList = document.getElementsByTagName("ol")[0];
var topEntry = document.querySelectorAll("#playerEntries li")[0];
blogList.insertBefore(newestEntry, topEntry);
}
function deleteEntry() {
var num2Delete = document.getElementsByName("entryNum")[0].value;
var blogList = document.getElementsByTagName("ol")[0];
var howManyEntries = blogList.length;
if (howManyEntries >= 1) {
var postToDelete = blogList[num2Delete - 1];
var deletedPost = blogList.removeChild(postToDelete);
}
}
</script>
</body>
</html>
You have to replace
<input type="submit" value="Submit" onclick="addEntry()"><br>
with
<input type="button" value="Submit" onclick="addEntry()"><br>
otherwise the form will be submitted and the page will reload. You can also use the submit function of the form but will you have to use preventDefault.
Also to make the deleteEntry function works, you can't use document.getElementsByTagName("ol")[0]; since you can't use .length on an element. Here's another way to do it :
function deleteEntry() {
var num2Delete = document.getElementsByName("entryNum")[0].value;
var blogList = document.querySelectorAll("ol > li");
var howManyEntries = blogList.length;
if (howManyEntries >= 1) {
var postToDelete = blogList[num2Delete - 1];
postToDelete.remove();
}
}

Code works in Chrome and Firefox, but doesn't work in IE11

I have this small program that basically compares to sets of numbers and then will let me know if there are any matches and what those matches are. It works just fine in Chrome and Firefox, but when I try it in IE11, and hit the button, nothing appears and it doesn't seem to work. I have looked at other forums and topics but nothing I have tried seems to work. Any ideas?
Heres the code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
<HTML><HEAD><META content="IE=5.0000" http-equiv="X-UA-Compatible">
<META http-equiv="Content-Type" content="text/html; charset=unicode">
<SCRIPT>
function check() {
var a = document.getElementById("a").value.split("\n").filter(function(num) { return num.length > 0 });
var b = document.getElementById("b").value.split("\n").filter(function(num) { return num.length > 0 });
var results = "";
var numMatchesFound = 0;
for (x = 0; x < a.length; x++) {
for (y = 0; y < b.length; y++) {
if (a[x] == b[y]) {
numMatchesFound++;
results += "<br>" + b[y];
}
}
}
results = "<br>Found " + numMatchesFound + " matches." + results;
document.getElementById("result").innerHTML = results;
}
</SCRIPT>
<META name="GENERATOR" content="MSHTML 10.00.9200.16798"></HEAD>
<BODY>
<H1>Match finder</H1>
<P> Entries can be words,
numbers, or whatever.</P>
<H2>Paste a list of entries, one per line, in this
box:</H2><TEXTAREA id="a" rows="10" cols="30"></TEXTAREA> <BR>
<H2>Paste another list of entries, one per line, in this box:</H2><TEXTAREA id="b" rows="10" cols="30"></TEXTAREA>
<BR><BUTTON onclick="check()" type="button">Check for matches</BUTTON> <BR>
<DIV id="result"></DIV>
</BODY>
</HTML>
Take a look at the "Developer Tools", in the "Console" tab:
Object doesn't support property or method 'filter'
File: test.html, Line: 7, Column: 1
Despite the function reportedly being supported as of IE9 (http://www.w3schools.com/jsref/jsref_filter.asp), and Microsoft describing how to use it (https://msdn.microsoft.com/en-us/library/ff679973(v=vs.94).aspx), this is not available for some reason.
Thank goodness for jQuery = )
Or try modifying your meta tags. Pretty sure you told IE to pretend like it was IE5. I stripped your meta tags out and it worked just fine.

Ping-Pong aka FizzBuzz test

I am new to programming and am currently stuck on the Ping-Pong aka FizzBuzz problem. (Make a webpage where the user is prompted to enter a number and every number up to that number is displayed. However, for multiples of three, the page prints "ping," for multiples of five, the page prints "pong," and for multiples of both three and five (15), the page prints "ping-pong.")
I've checked out other solutions on here (such as this one) and they've been helpful for understanding how to solve it. And I hope my javascript reflects that.
My problem is I'm stuck trying to take the input number from the form I have on the webpage and run it through the javascript, if that makes sense.
I'm pretty sure that part of my javascript is just a conglomeration of throwing everything I had at it, which is not the best. Could anyone check out my code and see what I'm doing wrong here?
Here's my HTML:
<!DOCTYPE html>
<html>
<head>
<link href="css/bootstrap.css" rel="stylesheet" type="text/css">
<link href="css/styles.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.11.2.js"></script>
<script src="js/scripts.js"></script>
<title>Ping-Pong Test</title>
</head>
<body>
<div class="container">
<h1>Ping Pong Test</h1>
<p>Let's play the Ping-Pong game. The Ping-Pong game is a simple test that involves loops, conditionals, and variables. Enter your number below to start</p>
<form id="start-form">
<label for="input-number">Your number:</label>
<input id="input-number" type="number">
<button type="submit" class="btn">Calculate</button>
</form>
<div id="end-number">
<ul id="results"></ul>
</div>
</div>
</body>
</html>
And my javascript:
$(document).ready(function () {
$("#start-form").submit(function(event) {
var a = document.getElementById("#input-number");
var num = a.elements[0].value;
var listItems = "";
var i;
for (var i = 1; i <= num; i++) {
if (i % 15 === 0) {
console.log("Ping-Pong");
}
else if (i % 3 === 0) {
console.log("Ping");
}
else if (i % 5 === 0) {
console.log("Pong");
}
else{
console.log(i);
};
event.preventDefault();
};
});
Again, I'm new, so if anyone could break it down step by step, I'd really appreciate it. Thanks.
It is not right:
var a = document.getElementById("#input-number");
Must be one of the below lines:
var a = document.getElementById("input-number");
// Or
var a = $("#input-number").get(0);
// Or
var a = $("#input-number")[0];
But it will not solve your problem. Looking deep into your code. I guess you need to have a form an then get the first element:
var a = document.getElementById("start-form");
var num = a.elements[0].value;
But you can simplify even more. Why not just do it:
// remove the a variable
var num = $("#input-number").val(); // get the input-number value
Based on your code I think you just need some syntax cleaned up in order for jquery to use the value from your form.
I took your code, stripped it down for clarity and made a fiddle out of it.
Here is the link:
http://jsfiddle.net/zwa5s3ao/3/
$(document).ready(function(){
$("form").submit(function(event){
var num = $('#input-number').val()
for (var i = 1; i <= num; i++) {
if (i % 15 === 0) {
$('#list').append('<li>'+"Ping-Pong"+'</li>');}
else if (i % 3 === 0) {
$('#list').append('<li>'+"Ping"+'</li>');}
else if (i % 5 === 0) {
$('#list').append('<li>'+"Pong"+'</li>');}
else{
$('#list').append('<li>'+i+'</li>');}
};
event.preventDefault();
});
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<title>Ping-Pong Test</title>
<body>
<form>
Your number:
<input type="number" name="input-number" id="input-number">
<input type="submit" value="Calculate">
</form>
<ul id="list"></ul>
</body>
Hope this helps!

jquery cookies when loaded are not replace old values. Instead they are being place to the side infinitely

Alright, first thing to note is this is my second day working with javascript, and my first time trying to implement cookies. That being said whenever it does manage to load the cookies it does not replace the values of the cookies. Instead it places the value next to the old one, ex. if the value is 1, and the cookie have .47 saved, it will become 1.47, and eventually it will expand as the script reruns it numbers like this pop up (0.60000000000000012.524.924924902490024900024900002490000024900000024...) I'm not sure what I am doing wrong here is my code.
<!doctype html>
<html>
<title>Power Plant </title>
<head>
<link rel="stylesheet" type="text/css" href="CSS/looksyo.css" />
<script type="text/javascript" src="javascript/main.js"></script>
<script type="text/javascript" src="javascript/jquery.js"></script>
<script type="text/javascript" src="javascript/jquery.cookie.js"></script>
<script src="javascript/jquery-migrate.js"></script>
<h1> Plant Power </h1>
</head>
<body>
<script type="text/javascript"> getCookies() </script>
<table>
<!-- First Column, this will be where I keep the Tender shiz -->
<td class=leftColumn>
Tender:
<span id="tender">0</span><br/> </br>
You gain tender based on a kilowatt second.
</td>
<!-- Second columns The BUTTON! Please wait while the button calibrates. -->
<td class=centerColumn>
<div class="buttonStyle">
<br /> </br>
Watt Button
<br /> </br>
<input type="submit" value="SaveTest" onClick=setCookies()></input>
<button type="submit" hidefocus=true onClick=wattClick(1)><span id="watts">0</span></button>
</div>
</td>
<!-- Third columns buildings -->
<td class=rightColumn>
<div id="crankStyle" >
<button type="submit" onClick=purchaseCrank()> Buy Cranks </button>
<span id="cranks">0</span> <br /> </br>
Crank Cost:<span id="crankCost">10</span>
</div>
</div>
</td>
</table>
</body>
</html>
And the js
//resources
var watts = 0;
var tender = 0;
//buildings
var cranks = 0;
//Gaining Watts from the watt button
function wattClick(number) {
watts = watts + number;
document.getElementById("watts").innerHTML = watts;
}
function purchaseCrank() {
var crankCost = Math.floor(10 * Math.pow(1.1,cranks));
if(tender > crankCost - 1) {
cranks = cranks + 1;
tender = tender - crankCost;
document.getElementById("cranks").innerHTML = cranks;
document.getElementById("tender").innerHTML = tender; };
var nextCost = Math.floor(10 * Math.pow(1.1,cranks));
document.getElementById("crankCost").innerHTML = nextCost;
};
//Building Passives
window.setInterval(function(){
wattClick(cranks);
}, 1000);
//For debugging
function tenderClick(number){
tender = tender + number;
document.getElementById("tender").innerHTML = tender;
};
//Ways to Gain Tender
window.setInterval(function(){
tenderClick(Math.round(10*watts/1000)/10);
}, 1000);
//Figuring out how to write cookies, yay.
//escaping the values before writing them
//var eWatts = escape(watts);
//var eTender = escape(tender);
//var eCranks = escape(cranks);
//This should write the needed cookies
function setCookies(){
$.cookie("watts", escape(watts), {expires: 10000});
$.cookie("tender", escape(tender), {expires: 10000});
$.cookie("cranks", escape(cranks), {expires: 10000});
}
function getCookies(){
check1 = $.cookie("watts");
check2 = $.cookie("tender");
check3 = $.cookie("cranks");
if (check1 == null || check2 == null || check3 == null) {
setCookies()
}
else
{
watts = unescape($.cookie("watts"));
tender = unescape($.cookie("tender"));
cranks = unescape($.cookie("cranks"));
document.getElementById("watts").innerHTML = watts;
document.getElementById("tender").innerHTML = tender;
document.getElementById("cranks").innerHTML = cranks;
};
};
I'm just not sure what I'm doing wrong when it comes to calling the cookies and putting them into place. I have read and tried implementing several methods and the problem either persist, or it won't have an effect.
From the symptom you described, it must has nothing to do with cookies.
It is obvious when you are doing the math, you are using string instead of numbers.
Javascript does not do automatic type conversion, also, it use '+' for both string concatenation and numeric addition.
Thus lines like:
cranks = cranks + 1;
Should be
cranks = parseFloat(cranks) + 1;

Categories

Resources