question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ad hoc way to get a random number in a range

See original GitHub issue

Does FsCheck define an ad hoc way to get a random number in a range? Particularly, a way that works with FsCheck.Xunit?

Let’s say that I want a randomly generated number in the range 1-100, or 1-8. While I could use a custom Arbitrary, this is sometimes too heavy-handed. Besides, a custom arbitrary affects all values of a particular type (int, byte, float, etc.), and that’s sometimes undesirable, because I want most numbers to be unconstrained, except for one or two. A motivating example is described below.

If there’s no current way to do this, I’d like to suggest a solution:

We could add a function that would take any number, and map it to the corresponding number in the required range.

It might look like this:

let y = Range.map Int32.MinValue Int32.MaxValue 1 100 x

This would take the 32-bit integer x and map it to a value in the range 1-100. This could be useful when FsCheck provides an unbounded int value.

The first two arguments are the original range from which x was drawn, in this case all 32-bit integers. The function can be partially applied so that it can be used in a more readable manner:

let y = x |> between 1 100

If there’s no existing feature to address this requirement, and this suggestion sounds like an appropriate solution, I’ll be happy to make a pull request.

Motivating example

I often need to get a number in a predetermined range. One recent example that came up was that I was doing Conway’s Game of Life, and I wanted to express the property that Any live cell with more than three live neighbours dies.

I already have a function that gives me all (8 of) the neighbouring cells of a cell, so in order to express this test case, I want to pick a number of neighbours from 4 to 8, and then select that number of neighbouring cells as live cells.

It’d be nice to be able to express that like this:

[<Property>]
let ``Any live cell with more than three live neighbours dies``
    (cell : int * int)
    (neighborCount : int) =
    let neighborCount = neighborCount |> between 4 8

    // The rest of the property goes here...

In this example, a custom Arbitrary is undesirable, because I want the integers in cell to be unconstrained.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
ploehcommented, Aug 26, 2015

@mausch, thank you, I didn’t know about Prop.forAll. That turns out to address the issue elegantly and flexibly, even with FsCheck.Xuni:

[<Property>]
let ``Any live cell with more than three live neighbours dies``
    (cell : int * int) =

    let nc = Gen.elements [4..8] |> Arb.fromGen
    Prop.forAll nc (fun neighborCount ->
        let liveNeighbors =
            cell
            |> neighbors
            |> shuffle
            |> Seq.take neighborCount
            |> Seq.toList

        let actual = getNextState (cell::liveNeighbors) cell

        Dead =! actual)

This almost deserves a blog post, unless you think there’s a good fit for it in the documentation somewhere!(?)

The only thing I’m not 100 % happy with is the extra indentation caused by the multi-line lambda function, but I am 95 % happy 😄

For my sake we can close the issue again.

0reactions
kurtschelfthoutcommented, Aug 26, 2015

Ok. I guess it is in the documentation, though if anything should be clarified, feel free to PR for that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

generate random number in a range c++ [duplicate]
First of, don't call srand multiple times, it will give very poor results. Second of, why are you just calling plain rand() instead...
Read more >
How to Generate a Random Number within Certain ...
first, we get a random floating number using Math.random() · next, we find the difference between the highest and lowest range · next,...
Read more >
How to generate random number in given range using ...
Method 1: Using Math.random() function: The Math.random() function is used to return a floating-point pseudo-random number between range [0,1), ...
Read more >
Exclude a range in a random range of numbers
No. For the simple problem of excluding a range of numbers, you could just use an ad hoc solution, e.g. (untested pseudocode):.
Read more >
RandomNumberGenerator - Godot Docs
Initializes the random number generator state based on the given seed value. A given seed will give a reproducible sequence of pseudo-random numbers....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found