Asked  6 Months ago    Answers:  5   Viewed   23 times

I was helping somebody out with his JavaScript code and my eyes were caught by a section that looked like that:

function randOrd(){
  return (Math.round(Math.random())-0.5);
}
coords.sort(randOrd);
alert(coords);

My first though was: hey, this can't possibly work! But then I did some experimenting and found that it indeed at least seems to provide nicely randomized results.

Then I did some web search and almost at the top found an article from which this code was most ceartanly copied. Looked like a pretty respectable site and author...

But my gut feeling tells me, that this must be wrong. Especially as the sorting algorithm is not specified by ECMA standard. I think different sorting algoritms will result in different non-uniform shuffles. Some sorting algorithms may probably even loop infinitely...

But what do you think?

And as another question... how would I now go and measure how random the results of this shuffling technique are?

update: I did some measurements and posted the results below as one of the answers.

 Answers

62

It's never been my favourite way of shuffling, partly because it is implementation-specific as you say. In particular, I seem to remember that the standard library sorting from either Java or .NET (not sure which) can often detect if you end up with an inconsistent comparison between some elements (e.g. you first claim A < B and B < C, but then C < A).

It also ends up as a more complex (in terms of execution time) shuffle than you really need.

I prefer the shuffle algorithm which effectively partitions the collection into "shuffled" (at the start of the collection, initially empty) and "unshuffled" (the rest of the collection). At each step of the algorithm, pick a random unshuffled element (which could be the first one) and swap it with the first unshuffled element - then treat it as shuffled (i.e. mentally move the partition to include it).

This is O(n) and only requires n-1 calls to the random number generator, which is nice. It also produces a genuine shuffle - any element has a 1/n chance of ending up in each space, regardless of its original position (assuming a reasonable RNG). The sorted version approximates to an even distribution (assuming that the random number generator doesn't pick the same value twice, which is highly unlikely if it's returning random doubles) but I find it easier to reason about the shuffle version :)

This approach is called a Fisher-Yates shuffle.

I would regard it as a best practice to code up this shuffle once and reuse it everywhere you need to shuffle items. Then you don't need to worry about sort implementations in terms of reliability or complexity. It's only a few lines of code (which I won't attempt in JavaScript!)

The Wikipedia article on shuffling (and in particular the shuffle algorithms section) talks about sorting a random projection - it's worth reading the section on poor implementations of shuffling in general, so you know what to avoid.

Tuesday, June 1, 2021
 
IvanH
answered 6 Months ago
53

You should probably not try to do anything special even if you could detect that a screenreader is running. Even if you get it right for one group of screenreader users, you may get it wrong for another group. It's best to concentrate on writing good clean HTML5 in the first place.

Note that not all screenreader users use text-to-speech; many use braille output. Additionally, other types of accessibility tools - such as content highlighters and voice input apps - use the same techniques and APIs (eg. DOM, MSAA) that screenreaders do, so any technique that "detects a screenreader" will likely detect these also - so you cannot assume that it means that the user is fully blind and using only speech.

As things currently stand, the audio tag is currently not universally accessible, different browsers have different levels of accessibility support - see HTML5 Accessibility and scroll down to audio for more details of current support. I've seen some pages that add HTML5-based controls plus javascript after the audio tag so they can provide their own UI to ensure that keyboard or screenreader users can play/stop the audio as needed. (Eventually, when browsers catch up, this should not be needed.)

As far as general accessibility goes, WCAG 2.0 (Web Content Accessibility Guidelines) recommends that any audio that plays automatically for more than 3 seconds should have an accessible means to pause or stop the audio. (I'd go even further and recommend against using any automatic audio - when using tabbed browsing, it's often impossible to determine which tab the audio is coming from.)

Friday, July 30, 2021
 
Sergey Ryabov
answered 4 Months ago
21

You could use a Fisher-Yates-Durstenfeld shuffle:

var shuffledQuestionArray = shuffle(yourQuestionArray);
var shuffledTopicArray = shuffle(yourTopicArray);

// ...

function shuffle(sourceArray) {
    for (var i = 0; i < sourceArray.length - 1; i++) {
        var j = i + Math.floor(Math.random() * (sourceArray.length - i));

        var temp = sourceArray[j];
        sourceArray[j] = sourceArray[i];
        sourceArray[i] = temp;
    }
    return sourceArray;
}
Monday, August 9, 2021
 
erotsppa
answered 4 Months ago
10

Use sample() to generate row-indices in a (pseudo-)random order and reorder the matrix using [.

## create a matrix A for illustration
A <- matrix(1:25, ncol = 5)

Giving

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25

Next, generate a random order for the rows

## generate a random ordering
set.seed(1) ## make reproducible here, but not if generating many random samples
rand <- sample(nrow(A))
rand

This gives gives

> rand
[1] 2 5 4 3 1

Now use that to reorder A

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
> A[rand, ]
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    7   12   17   22
[2,]    5   10   15   20   25
[3,]    4    9   14   19   24
[4,]    3    8   13   18   23
[5,]    1    6   11   16   21
Tuesday, August 17, 2021
 
steros
answered 4 Months ago
33

get_Keys() is indeed a valid (and recommended) way to access the Keys property of a dictionary without risking collision with a user-defined key.

The method works as expected (also on other collections, any PowerShell version and .Net Core):

Please beware that this only works on dictionaries ([hashtable], [ordered], [SortedList] etc.) - as it's inherited from the System.Collections.IDictionary interface.

The reason get_Keys() isn't listed in the public documentation is that it's intentionally hidden.

To understand why, we first need to understand the nature of properties in .NET

Properties in .NET

In .NET, data types can have different kinds of members. In the (C#) example below we define a class with two members, a field and a method:

class MyClass
{
    int MyField;

    int MyMethod(string n = "")
    {
        return int.Parse(n);
    }
}

The interesting thing to notice here is that the field acts like a variable - we can reference it to obtain the value of whatever integer is stored in MyField and we can assign a (new) value to it. The method, on the other hand, acts like a function - we can call it, including passing parameter values to it, and it can return a value.

But .NET has a third kind of member type that acts as a bit of a hybrid between a field and a method, and it looks a bit like this (in the case of a dictionary):

class MyDictionary
{
    string[] Keys
    {
        string[] _keys;

        get
        {
            return _keys;
        }
        set
        {
            throw new InvalidOperationException("Don't mess with the keys!");
        }
    }
}

This is known as a property - from a user perspective, the Keys property will act just like a field - we can reference it to resolve its value and we can (attempt to) assign to it - but from an implementer's perspective we have a lot more control over it's behavior, like being able to (conditionally) throw an exception on assignment.

Now, when the above code is compiled, the C# compiler needs to store the get and set methods somewhere so that the CLR knows to execute them when someone tries to resolve the Keys member at runtime.

The convention is to generate them as regular class methods, named by prepending get_ and set_ to the property name in question. The compiler further marks these methods with the SpecialName attribute flag, allowing editors and analyzers to hide them in user interfaces and auto-completers - which is exactly why the method name doesn't automatically show up in intellisense and the likes.

Discovering property getters/setters

*In PowerShell classes, members are always either methods or properties, so in the following I'll use this PowerShell class definition for the examples:

class StackOverflowUser
{
  [string]$Name
  [int]$ID

  StackOverflowUser([string]$name, [int]$id)
  {
    $this.Name = $name
    $this.ID   = $ID
  }
}

$Mathias = [StackOverflowUser]::new("Mathias R. Jessen", 712649)

Using Get-Member

You can discover the automatic getters and setters associated with a property using Get-Member -Force:

PS C:> $Mathias |Get-Member ?et_* -Force


   TypeName: StackOverflowUser

Name     MemberType Definition
----     ---------- ----------
get_ID   Method     int get_ID()
get_Name Method     string get_Name()
set_ID   Method     void set_ID(int )
set_Name Method     void set_Name(string )

Here we can see the getter and setter methods associated with $ID and $Name.

Using reflection

We can also find these directly from a [type] object:

PS C:> $IDPropertyInfo = [StackOverflowUser].GetProperty("ID")
PS C:> $IDPropertyInfo.GetMethod

Name                       : get_ID
DeclaringType              : StackOverflowUser
ReflectedType              : StackOverflowUser
MemberType                 : Method
MetadataToken              : 100663299
Module                     : RefEmit_InMemoryManifestModule
IsSecurityCritical         : True
IsSecuritySafeCritical     : False
IsSecurityTransparent      : False
MethodHandle               : System.RuntimeMethodHandle
Attributes                 : PrivateScope, Public, HideBySig, SpecialName
CallingConvention          : Standard, HasThis
ReturnType                 : System.Int32
ReturnTypeCustomAttributes : Int32
ReturnParameter            : Int32
IsCollectible              : True
IsGenericMethod            : False
IsGenericMethodDefinition  : False
ContainsGenericParameters  : False
MethodImplementationFlags  : Managed
IsAbstract                 : False
IsConstructor              : False
IsFinal                    : False
IsHideBySig                : True
IsSpecialName              : True
IsStatic                   : False
IsVirtual                  : False
IsAssembly                 : False
IsFamily                   : False
IsFamilyAndAssembly        : False
IsFamilyOrAssembly         : False
IsPrivate                  : False
IsPublic                   : True
IsConstructedGenericMethod : False
CustomAttributes           : {}

Notice that the getter above has the SpecialName attribute as discussed above

Note: output above is from PowerShell 7 and will be slightly different in Windows PowerShell due to changes in the reflection/type system APIs in .NET Core

I hope this explains :)

Friday, August 20, 2021
 
commonpike
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share