Is initialSeed supposed to provide a different seed each time it is called? The following code always provides the same value:
import Graphics.Element exposing (show)
import Random exposing(float, generate, initialSeed)
main =
show (generate (float 0 1 ) (initialSeed 31415))
If this code is behaving correctly, would you kindly give a pointer on the usage of random numbers and Random.generate.
initialSeed is a function which given an Int produces a Seed which can then be used in the generate function. Because Elm is purely function, giving generate the same Generator and Seed will always produce the same value. However, generate also returns the next Seed to be used in your next call to generate. This in allows you to reproduce the same sequence of randomly generated values.
Example usage:
import Random
import Graphics.Element as Element
-- Int Generator that computes random numbers in the range [0, 10]
intGenerator = Random.int 0 10
-- Change this to get different sequences.
seed = Random.initialSeed 42
--seed = Random.initialSeed 1234
--seed = Random.initialSeed 0
-- Generates a random x and returns the next seed to be used. Note:
-- This will always return the same x because it uses the same seed
-- this is a result of Elm being purely functional. However,
-- because this returns a new seed, you can use that to get the next
-- random value in the sequence
(x, seed') = (Random.generate intGenerator seed)
-- Generate the next element in the sequence
(y, seed'') = (Random.generate intGenerator seed')
(z, seed''') = (Random.generate intGenerator seed'')
main = Element.show [x, y, z]
on share-elm.com: http://share-elm.com/sprout/55c766b4e4b06aacf0e8be1b
Hope this helps!
Using Random is super-easy in Elm 0.15. (I assume you understand how Elm naturally separates data and code into model, update, and view. If your understanding of Elm architecture is shaky, read The Elm Architecture tutorial and simple explanation of model-view-update pattern).
The most important function is generate, it returns a pair: a random value and a new seed. This new seed you can pass into generate again, to yield a new random value and yet another seed. However passing the same seed yields the same “random” value. The below code renders 59:
import Graphics.Element exposing (show)
import Random exposing (generate, int, initialSeed)
main =
let (number, seed) = generate (int 0 99) (initialSeed 1234)
in show number
You need to save this new seed between any 2 random value generations somehow. And each time you use generate, pass the new seed instead of the old one. How do you do that?
You store the seed inside your model and make sure that during update stage you overwrite the old seed with the new seed:
import Graphics.Element exposing (Element, show)
import Mouse exposing (clicks)
import Random exposing (Seed, initialSeed, generate, int)
import Signal exposing (Signal, foldp)
seed0 = initialSeed 1234
type alias Model = { num : Int, seed : Seed }
defaultModel : Model
defaultModel = { num = 0, seed = seed0 } -- initial seed in the model
update : () -> Model -> Model
update _ model =
let (newNum, newSeed) = generate (int 0 99) model.seed -- new value and new seed
in { model | num <- newNum, seed <- newSeed } -- update model with new seed
view : Model -> Element
view model = show model.num
-- new random value each time mouse clicked
main = Signal.map view <| foldp update defaultModel clicks
Related
I am writing a unit test for a function and in the real function I have:
rng = default_rng()
...
... # a little while later
while N<50:
...
idx = rng.integers(100)
How do I mock out either the variable idx or the call to rng.integers? In other words, I'd like to make idx pull from a simple ordered list [0, 1, 2, ...].
Every time I try #mock.patch('numpy.random.default_rng', side_effects=[0, 1, 2, ...]) decorating the test function, the code 'runs' but doesn't do what I am hoping. If I replace the above to 'numpy.random.default_rng.integers I get an error that says default_rng has no attribute integers (I believe bc it is a generator object). I've tried a number of different iterations using #mock.patch.object but still to no avail.
There are some problems with your patching. First, you are obviously using from numpy.random import default_rng, so you have to patch the default_rng instance in your module - see where to patch.
Second, integers is called on the instance of default_rng, not on the class, so you first have to get the instance of the mock, with is done via return_value.
And third: it's called side_effect, not side_effects (though that may just be a typo in your question).
So a working version could look like this (adapted a bit to actually be able to test something):
sut.py
from numpy.random import default_rng
def get_random():
rng = default_rng()
idx = 0
while idx < 50:
idx = rng.integers(100)
return idx
test_sut.py
#mock.patch('sut.default_rng')
def test_get_random(mocked):
mocked.return_value.integers.side_effect = range(60)
assert do_something() == 50
I stumbled upon this challenge on stackoverflow while learning about property based testing in scala using ScalaCheck.
Find the smallest positive integer that does not occur in a given sequence
I thought of trying to write a generator driven property based test for this problem to check the validity of my program but can't seem to be able to think of a how to write a relevant test case. I understand that I could write a table driven property based testing for this use case but that limit the number of properties I could test this algo with.
import scala.annotation.tailrec
object Solution extends App {
def solution(a: Array[Int]): Int = {
val posNums = a.toSet.filter(_ > 0)
#tailrec
def checkForSmallestNum(ls: Set[Int], nextMin: Int): Int = {
if (ls.contains(nextMin)) checkForSmallestNum(ls, nextMin + 1)
else nextMin
}
checkForSmallestNum(posNums, 1)
}
}
Using Scalatest's (since you did tag scalatest) Scalacheck integration and Scalatest matchers, something like
forAll(Gen.listOf(Gen.posNum[Int]) -> "ints") { ints =>
val asSet = ints.toSet
val smallestNI = Solution.solution(ints.toArray)
asSet shouldNot contain(smallestNI)
// verify that adding non-positive ints doesn't change the result
forAll(
Gen.frequency(
1 -> Gen.const(0),
10 -> Gen.negNum[Int]
) -> "nonPos"
) { nonPos =>
// Adding a non-positive integer to the input shouldn't affect the result
Solution.solution((nonPos :: ints).toArray) shouldBe smallestNI
}
// More of a property-based approach
if (smallestNI > 1) {
forAll(Gen.oneOf(1 until smallestNI) -> "x") { x =>
asSet should contain(x)
}
} else succeed // vacuous
// Alternatively, but perhaps in a less property-based way
(1 until smallestNI).foreach { x =>
asSet should contain(x)
}
}
Note that if scalatest is set to try forAlls 100 times, the nested property check will check values 10k times. Since smallestNI will nearly always be less than the number of trials (as listOf rarely generates long lists), the exhaustive check will in practice be faster than the nested property check.
The overall trick, is that if something is the least positive integer for which some predicate applies, that's the same as saying that for all positive integers less than that something the predicate does not apply.
There is a function noiseSeed(int) to set the seed for a program, but is there any way to print the seed of a program when it begins?
I am making generative art sketches and it would be more convenient to store just a seed number for a result than an entire image.
You can't get the default random seed value.
Check out Processing's source code (specifically the random() and randomSeed() functions) to see that Processing uses an instance of the Random class to generate random numbers. That class does not have a public way to access its seed value, and even if it did, the internalRandom used by Processing isn't accessible to you anyway.
What you can do is create your own seed value and then store that in your own variable. Something like this:
long seed;
void setup(){
seed = (long)random(1000);
randomSeed(seed);
println("Seed value: " + seed);
}
How you come up with that seed is up to you. Here I'm generating a random seed between 0 and 1000, but in real life it can be any long value.
You could then also input this from the user in order to have repeatable random behavior based on the input value.
I would like to create a form in Elm that takes 4 required inputs:
3 floating point values
1 input which can take the values of "long" or "short" (presumably) this would be a drop-down
When the values are entered, a computation occurs that yields a single line of output based on these values.
I have this working as a command-line Python program:
#!/usr/bin/env python
from __future__ import print_function
# core
import logging
# pypi
import argh
# local
logging.basicConfig(
format='%(lineno)s %(message)s',
level=logging.WARN
)
def main(direction, entry, swing, atr):
entry = float(entry)
swing = float(swing)
atr = float(atr)
if direction == 'long':
sl = swing - atr
tp = entry + (2 * atr)
elif direction == 'short':
sl = swing + atr
tp = entry - (2 * atr)
print("For {0} on an entry of {1}, SL={2} and TP={3}".format(
direction, entry, sl, tp))
if __name__ == '__main__':
argh.dispatch_command(main)
but want to use Elm to create a web UI for it.
This isn't an ideal first introduction to Elm, since it takes you through a few of Elm's more difficult areas: mailboxes and the Graphics.Input library. There is also not an easy-to-deploy number input, so I've only implemented the dropdown; you'd use Graphics.Input.Field (which can get particularly dicey).
A mailbox is basically a signal that the dropdown input can send a message to. I've chosen for that message to be a function, specifically, how to produce a new state from the old one. We define state to be a record type (like a Python named tuple), so saving the direction involves storing the new direction in the record.
The text is rendered using a convenience function that makes it monospace. There's a whole text library you can use, but Elm 0.15 does not have string interpolation, so you're stuck with the quite ugly appends.
Finally, there's not much on an Elm community on SO, but you're welcome to join the mailing list where questions like this are welcomed. That being said, you really should try to dive into Elm and learn the basics so you can ask a more specific question. This is true of almost any language, library or framework - you have to do some basic exercises before you can write "useful" code.
import Graphics.Input as Input
import Graphics.Element as Element exposing (Element)
mailbox = Signal.mailbox identity
type Direction = Short | Long
type alias State = {entry : Float, swing : Float, atr : Float, dir : Direction}
initialState : State
initialState = State 0 0 0 Short
dropdown : Element
dropdown =
Input.dropDown
(\dir -> Signal.message mailbox.address (\state -> {state| dir <- dir}))
[("Short", Short), ("Long", Long)]
state : Signal State
state = Signal.foldp (<|) initialState mailbox.signal
render : State -> Element
render state =
dropdown `Element.above`
Element.show ("For "++(toString state.dir)++" on an entry of "++(toString state.entry) ++
", SL="++(toString (sl state))++" and TP="++(toString (tp state)))
main = Signal.map render state
-- the good news: these are separate, pure functions
sl {entry, swing, atr, dir} =
case dir of
Long -> swing - atr
Short -> swing + atr
tp {entry, swing, atr, dir} =
case dir of
Long -> entry + (2*atr)
Short -> entry - (2*atr)
Update: I wrote an essay on mailboxes and how to use them.
For fun, I am trying to write a simple simulation of the
Monty Hall problem
problem using F#.
I have created a function getShow which returns an array of three booleans (representing doors), one of which is randomly true (it has a car behind it) and the other two false.
let getShow =
let doorWithCar = System.Random().Next(3)+1
[|for door in 1..3 -> door = doorWithCar|]
Now when I try to get a sequence of shows using yield to call the getShow function, I keep getting the first random show repeated (I am guessing because of the way closures work in F#).
let shows =
seq { for i in 1 .. 10 do yield getShow} // Keeps generating the same show over and over
What is the correct way to call the getShow function using yield so that it actually calls the function and gets a new random array?
getShow is a value and not a function, so it's calculated once and you keep yielding the same value. To turn it into a function you have to add (). Also, you keep creating a new Random instance, which is probably initialized with the same time seed, not giving you what you want. Try this instead:
let random = System.Random()
let getShow() =
let doorWithCar = random.Next(3)+1
[|for door in 1..3 -> door = doorWithCar|]
let shows =
seq { for i in 1 .. 10 do yield getShow()}