I am trying to do a poor-mans version of multivariate testing on our website. What I want to do is use a piece of Javascript that will randomly choose between two URLS that I declare within the Javascript and use that as the source URL for the location.replace function.
I've not tried much because I am not a programmer in any sense of the word. If I have some code I can generally make my way through it, understand it and make small changes.
Here is the code that I am currently using:
location.replace("https://www.example.com/pageA.html");
What I want to happen is that when I fire the location.replace code it will will either choose
https://www.example.com/pageA.html
OR
https://www.example.com/pageB.html
I think I have to put all this in an array?
Any help would be most appreciated.
Here is an array based version.
You can have multiple amounts of URLs in the array and it will choose from them.
let urls = [
'https://www.example.com/pageA.html',
'https://www.example.com/pageB.html'
];
location.replace(Math.floor(Math.random() * urls.length - 1));
If you just want to randomly choose between two options, you could do something like this:
let rand = Math.floor(Math.random * 2)
if(rand){
location.replace("https://www.example.com/pageA.html");
}else{
location.replace("https://www.example.com/pageB.html");
}
Math.random will return a random float between 0 and 1, so multiplying by 2 and rounding down will give either 0 or 1.
0 will evaluate to false and 1 to true.
Related
I am trying to understand how to approach math problems such as the following excerpt, which was demonstrated in a pagination section of a tutorial I was following.
const renderResults = (arrayOfItems, pageNum = 1, resultsPerPage = 10) => {
const start = (pageNum - 1) * resultsPerPage;
const end = pageNum * resultsPerPage;
arrayOfItems.splice(start, end).forEach(renderToScreenFunction);
};
In the tutorial this solution was just typed out and not explained, which got me thinking, had I not seen the solution, I would not have been able to think of it in such a way.
I understood the goal of the problem, and how splice works to break the array into parts. But it was not obvious to me how to obtain the start and end values for using the splice method on an array of of indefinite length. How should have I gone about thinking to solve this problem?
Please understand, I am learning programming in my spare time and what might seem simple to most, I have always been afraid and struggle with math and I am posting this question in hopes to get better.
I would really appreciate if anyone could explain how does one go about solving such problems in theory. And what area of mathematics/programming should I study to get better at such problems. Any pointers would be a huge help. Many thanks.
OK, so what you're starting with is
a list of things to display that's, well, it's as long as it is.
a page number, such that the first page is page 1
a page size (number of items per page)
So to know which elements in the list to show, you need to think about what the page number and page size say about how many elements you have to skip. If you're on page 1, you don't need to skip any elements. What if you're on page 5?
Well, the first page skips nothing. The second page will have to skip the number of elements per page. The third page will have to skip twice the number of elements per page, and so on. We can generalize that and see that for page p, you need to skip p - 1 times the number of elements per page. Thus for page 5 you need to skip 4 times the number of elements per page.
To show that page after skipping over the previous pages is easy: just show the next elements-per-page elements.
Note that there are two details that the code you posted does not appear to address. These details are:
What if the actual length of the list is not evenly divisible by the page size?
What if a page far beyond the actual length of the list is requested?
For the first detail, you just need to test for that situation after you've figured out how far to skip forward.
Your function has an error, in the Splice method
arrayOfItems.splice(start, end).forEach(renderToScreenFunction);
The second argument must be the length to extract, not the final
index. You don't need to calculate the end index, but use the
resultsPerPage instead.
I've rewrite the code without errors, removing the function wrapper for better understanding, and adding some comments...
// set the initial variables
const arrayOfItems =['a','b','c','d','e','f','g','h','i','j','k','l','m'];
const pageNum = 2;
const resultsPerPage = 5;
// calculate start index
const start = (pageNum - 1) * resultsPerPage; // (2-1)*5=5
// generate a new array with elements from arrayOfItems from index 5 to 10
const itemsToShow = arrayOfItems.splice(start, resultsPerPage) ;
// done! output the results iterating the resulting array
itemsToShow.forEach( x=> console.log(x) )
Code explanation :
Sets the initial parameters
Calculate the start index of the array, corresponding to the page you try to get. ( (pageNum - 1) * resultsPerPage )
Generates a new array, extracting resultsPerPage items from arrayOfItems , starting in the start index (empty array is returned if the page does not exist)
Iterates the generated array (itemsToShow) to output the results.
The best way to understand code, is sometimes try to run it and observe the behavior and results.
A disclaimer: I'm not familiar with Javascript. I've merely cobbled together a basic understanding of what I need to do for this task from Stack Overflow and other resources. My apologies if something below is unclear.
My problem: I need to generate a random number between 0 and 8,764, using Javascript, that will not repeat itself between Qualtrics survey responses.
Currently, I've found code to create an array that contains all numbers between 0 and 8,764, shuffles the array, and pops the last number off the end of the array.
It then adds embedded data to Qualtrics with that popped number, and I can then pipe the embedded data into a Qualtrics question to display it to my survey respondent. See below:
Qualtrics.SurveyEngine.addOnReady(function()
{
for (var i = 0, ar = []; i < 8; i++) {
ar[i] = i;
}
ar.sort(function () {
return Math.random() - 0.5;
});
var randomnumber = ar.pop();
Qualtrics.SurveyEngine.addEmbeddedData("randomnumber", randomnumber);
});
However, as far as I can tell, this Javascript code "resets" itself between survey responses, meaning it will re-create and re-shuffle the array each time a new respondent enters the survey. I'd like to find a way to make it so that it will be impossible for a new respondent to see the same popped "randomnumber" as a previous respondent. So, if the first survey respondent saw a 1, then the next survey respondent could see any number besides a 1 (let's say they see a 100 instead), and the next respondent could see any number except a 1 or a 100, etc etc.
I think it's possible to use embedded data in Javascript code and manipulate it (see here). It seems like there might be a way to access the randomnumber embedded data and write Javascript code to not remove any numbers from the array that match one of the previously popped randomnumbers. I lack the technical knowledge to execute this, if it's even the best way to accomplish the task.
Any and all help appreciated!
You can do what you want with Advanced Randomization in Qualtrics.
Set up a multiple choice question with your numbers 0 through 8,764 as the choices. Then use Advanced Randomization to select a random subset of 1 from all the numbers and click "Evenly Present" (Evenly Present is what tells Qualtrics to use every number before reusing any). Use JavaScript to hide the multiple choice question:
$(this.questionId).hide();
Now you can pipe your unique random number into a subsequent question. For example:
${q://QID1/ChoiceGroup/DisplayedChoices}
I need a random number which I will be storing in the database per record and that (the generated random number)too should not repeat in future. So is Math.random() function is good for that?
Thanks in advance
Random is random and statistically it will repeat somewhere in the future. What you can do is combine something unique with a random part - for example use the unix timestamp with a random number.
function getRand(){
return new Date().getTime().toString() + Math.floor(Math.random()*1000000);
}
Math.random() will not give you a unique number, in general it will not even give you a real random number.
You can try to use a datetime-based random algorythm, or go for a random number and then check if it's already in your database, but both approaches are not 100% save. There is pretty much only one way to ensure the number you store is unique, which is on database level.
You can see here for GUID generator for unique keys for your DB. Also there you can find a lot of good information about random mechanisms
Create GUID / UUID in JavaScript?
time + increment + random:
var newGuid = (function() {
var guid = parseInt(Math.random() * 36);
return function newGuid() {
return Date.now().toString(36) + (guid++ % 36).toString(36) + Math.random().toString(36).slice(2, 4);
};
})();
If you look at the specs of math.random, you will see that is defined as quasi-random number generator, meaning, it is not REALLY random. Moreover, a real random number generator will for sure repeat a result somewhere along the line BUT, when this happens, the series following this repetition will not resemble the series that followed the first appearance of the number.
Now, you mentioned that you need to store this in a database. Why don't you use a SEQUENCE (in Oracle; other DBMS have different mechanisms for this)? This will warrant that any used number will NEVER be reused. Moreover, if you don't want to use numbers in a sequence, you can using the value of this sequence as the seed for a random number (or a hashing). This will give you uniqueness to quite many digits.
I'm tried to make some world generation mechanism using Math.random() whenever I needed something random, but then decided that I wanted it seed-based, so, given a seed, I changed all of the Math.random() to Math.sin(seed++)/2+0.5, hoping it would do the same thing, but would be the same if the seed was the same seed.
Then someone made me notice that the sin wave hasn't got even distribution, and finally I saw why some of my code was working strangely.
I was wondering if there was a simple fix, or if there isn't, another very simple seed based randomizer like this
So, I looked at your method, t1wc, and I found that it isn't actually evenly distributed. It is significantly more likely to spit out numbers near 0 or near 1 than it is to spit out numbers near 0.5, for example. This is just a consequence of the way that the sine function works.
Instead, you might try using a method called Blum Blum Shub (named after the authors of the original paper, wonderfully). It is evenly distributed and quite fast. Given a seed, it works as follows:
Square the seed and put the result in a temporary variable (x).
Take the mod of x base M.
M is a product of two large primes.
The value of x is a new seed to be used for future calculations.
Return x/M as your pseudo-random number. It will be evenly distributed between 0 and 1.
Below is a simple implementation of a Blum Blum Shub:
var SeededRand = function(seed, mod1, mod2)
{
return function()
{
seed = (seed*seed) % (mod1*mod2);
return seed/(mod1*mod2);
};
};
If you want to make a new random number generator, you just call:
var rand = SeededRand(seed, mod1, mod2);
Where seed is some initial seed (1234567890 works well), and mod1 and mod2 are some large primes (7247 and 7823 work well). rand is just a variable that I've defined to hold the output.
Now, to start getting random values, you just call:
rand();
Which will spit out a different value each time you run it.
If you have any questions, please ask!
There is a very nice seed-based randomizing script already made. It can be found here.
ok guys, found out this is what I'm really looking for:
(((Math.sin(seed.value++)/2+0.5)*10000)%100)/100
It sends out even spreaded numbers, and I guess it's a lot simpler than any other number generator I've seen
I have some code from someone but wondering why they might have used a function like this.
this.viewable= 45;
getGroups: function() {
return Math.ceil( this.getList().length / this.viewable );
}
Why would they divide the list length by a number viewable.
The result is the amount of items that should be rendered on the screen.
Why not just say 45 be the number. Is it meant to be a percentage of the list. Usually I will divide a large value by a smaller value to get the percentage.
Sorry if this seems like a stupid math question but my Math skills are crap :) And just trying to understand and learn some simple Math skills.
It's returning the number of groups (pages) that are required to display the list. The reason it's declared as a variable (vs. using the constant in the formula) is so that it can be modified easily in one place. And likely this is part of a plugin for which the view length can be modified from outside, so this declaration provides a handle to it, with 45 being the default.
That will give the number of pages required to view them all.
I would guess you can fit 45 items on a page and this is calculating the number of pages.
Or something similar to that?
This would return the total number of pages.
Total items = 100 (for example)
Viewable = 45
100 / 45 = 2.22222....
Math.ceil(2.2222) = 3
Therefore 3 pages
judging by the function name "getGroups", viewable is the capacity to show items (probably some interface list size).
By doing that division we know how many pages the data is to be divided (grouped) in order to be viewed on the interface. The ceil functions guarantees that we don't left out partial pages, if we had come records left that don't fill a complete page, we still want to show them and therefor make them count for a page.