Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a good way to share the seed of random between modules (in python)?

I have a project with different main files (for different simulations). When I run one of the mainfiles, it should set a seed to random (and numpy.random), and all the modules in the project should use that seed.

I don't find a good way to do this. I have a file globals.py with this:

import random

myRandom=None


def initSeed(seed):
    global myRandom
    myRandom =random.Random(seed)

then from a main I do:

if __name__ == "__main__":

    seed=10
    globals.initSeed(seed)
...

Then in the modules that main calls, I do:

from globals import myRandom

But myRandom has the value None in the module (even though I modified it in main!). Why, and how to fix it? Is there a nicer way?

like image 984
rgalhama Avatar asked Mar 30 '16 09:03

rgalhama


People also ask

How do I create a random seed in Python?

In pure Python, you use random. seed() to set the seed, and then you may use random. randint() to draw a random integer, for example: Drawing four random integers after setting a seed.

How does random seed work in Python?

How Seed Function Works ? Seed function is used to save the state of a random function, so that it can generate same random numbers on multiple executions of the code on the same machine or on different machines (for a specific seed value). The seed value is the previous value number generated by the generator.

What is seed in Numpy random?

The numpy random seed is a numerical value that generates a new set or repeats pseudo-random numbers. The value in the numpy random seed saves the state of randomness. If we call the seed function using value 1 multiple times, the computer displays the same random numbers.

How does random seed work?

A random seed is a starting point in generating random numbers. A random seed specifies the start point when a computer generates a random number sequence. This can be any number, but it usually comes from seconds on a computer system's clock (Henkemans & Lee, 2001).


2 Answers

I'd use a file to avoid global and to separate data and logic a bit.

seed_handler.py

# file that stores the shared seed value 
seed_val_file = "seed_val.txt"

def save_seed(val, filename=seed_val_file):
    """ saves val. Called once in simulation1.py """
    with open(filename, "wb") as f:
        f.write(str(val))

def load_seed(filename=seed_val_file):
    """ loads val. Called by all scripts that need the shared seed value """
    with open(filename, "rb") as f:
        # change datatype accordingly (numpy.random.random() returns a float)
        return int(f.read())

simulation1.py

import random
import seed_handler

def sim1():
    """ creates a new seed and prints a deterministic "random" number """
    new_seed = int("DEADBEEF",16) # Replace with numpy.random.random() or whatever
    print "New seed:", new_seed
    # do the actual seeding of the pseudo-random number generator
    random.seed(new_seed)
    # the result
    print "Random:  ", random.random()
    # save the seed value so other scripts can use it
    seed_handler.save_seed(new_seed)

if __name__ == "__main__":
    sim1()

simulation2.py

import random
import seed_handler

def sim2():
    """ loads the old seed and prints a deterministic "random" number """
    old_seed = seed_handler.load_seed()
    print "Old seed:", old_seed
    # do the actual seeding of the pseudo-random number generator
    random.seed(old_seed)
    # the result
    print "Random:  ", random.random()

if __name__ == "__main__":
    sim2()

Output:

user@box:~/$ python simulation1.py 
New seed: 3735928559
Random:   0.0191336454935

user@box:~/$ python simulation2.py 
Old seed: 3735928559
Random:   0.0191336454935

ADDENDUM

I just read in the comments that this is for research. At the moment, executing simulation1.py overwrites the stored seed value; this might not be desirable. One could add one of these features:

  1. save as json and load to dictionary; that way nothing would get overwritten and every seed value could have notes, a timestamp and a user-generated label associated with it.
  2. simply prompt the user for a yes/no to overwriting the existing value.
like image 144
jDo Avatar answered Sep 23 '22 11:09

jDo


  1. As mentioned by @jDo in comment, renamed globals.py into randGlobal.py.

  2. Added a module testResult.py for testing.


randGlobal.py

import random

def initSeed(seed):
    # declare
    global myRandom
    myRandom = random.Random(seed)

testResult.py

import randGlobal

def randOutput():
    return randGlobal.myRandom.random()

main.py

import randGlobal

# Add a module for testing
import testResult


def test():
    result = testResult.randOutput()
    print result


# main
if __name__ == "__main__":

    seed=10
    randGlobal.initSeed(seed)
    # after init, hava a test
    test()
like image 36
davidlatwe Avatar answered Sep 24 '22 11:09

davidlatwe