mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-22 06:50:47 -04:00
94 lines
3.0 KiB
Plaintext
94 lines
3.0 KiB
Plaintext
###########################################################
|
|
# RapydScript Standard Library
|
|
# Author: Alexander Tsepkov
|
|
# Copyright 2013 Pyjeon Software LLC
|
|
# License: Apache License 2.0
|
|
# This library is covered under Apache license, so that
|
|
# you can distribute it with your RapydScript applications.
|
|
###########################################################
|
|
|
|
|
|
# basic implementation of Python's 'random' library
|
|
|
|
# JavaScript's Math.random() does not allow seeding its random generator, to bypass that, this module implements its own
|
|
# version that can be seeded. I decided on RC4 algorithm for this.
|
|
|
|
# please don't mess with this from the outside
|
|
|
|
_$rapyd$_seed_state = {
|
|
'key': [],
|
|
'key_i': 0,
|
|
'key_j': 0
|
|
}
|
|
|
|
_$rapyd$_get_random_byte = def():
|
|
_$rapyd$_seed_state.key_i = (_$rapyd$_seed_state.key_i + 1) % 256
|
|
_$rapyd$_seed_state.key_j = (_$rapyd$_seed_state.key_j + _$rapyd$_seed_state.key[_$rapyd$_seed_state.key_i]) % 256
|
|
_$rapyd$_seed_state.key[_$rapyd$_seed_state.key_i], _$rapyd$_seed_state.key[_$rapyd$_seed_state.key_j] = \
|
|
_$rapyd$_seed_state.key[_$rapyd$_seed_state.key_j], _$rapyd$_seed_state.key[_$rapyd$_seed_state.key_i]
|
|
return _$rapyd$_seed_state.key[(_$rapyd$_seed_state.key[_$rapyd$_seed_state.key_i] + \
|
|
_$rapyd$_seed_state.key[_$rapyd$_seed_state.key_j]) % 256]
|
|
|
|
def seed(x=Date().getTime()):
|
|
if type(x) is 'number':
|
|
x = x.toString()
|
|
elif type(x) is not 'string':
|
|
raise TypeError("unhashable type: '" + type(x) + "'")
|
|
for i in range(256):
|
|
_$rapyd$_seed_state.key[i] = i
|
|
j = 0
|
|
for i in range(256):
|
|
j = (j + _$rapyd$_seed_state.key[i] + x.charCodeAt(i % x.length)) % 256
|
|
_$rapyd$_seed_state.key[i], _$rapyd$_seed_state.key[j] = _$rapyd$_seed_state.key[j], _$rapyd$_seed_state.key[i]
|
|
seed()
|
|
|
|
def random():
|
|
n = 0
|
|
m = 1
|
|
for i in range(8):
|
|
n += _$rapyd$_get_random_byte() * m
|
|
m *= 256
|
|
return n / 18446744073709551616
|
|
|
|
# unlike the python version, this DOES build a range object, feel free to reimplement
|
|
def randrange():
|
|
return choice(range.apply(this, arguments))
|
|
|
|
def randint(a, b):
|
|
return int(random()*(b-a+1) + a)
|
|
|
|
def uniform(a, b):
|
|
return random()*(b-a) + a
|
|
|
|
def choice(seq):
|
|
if seq.length > 0:
|
|
return seq[Math.floor(random()*seq.length)]
|
|
else:
|
|
raise IndexError()
|
|
|
|
# uses Fisher-Yates algorithm to shuffle an array
|
|
def shuffle(x, random_f=random):
|
|
for i in range(x.length):
|
|
j = Math.floor(random_f() * (i+1))
|
|
x[i], x[j] = x[j], x[i]
|
|
return x
|
|
|
|
# similar to shuffle, but only shuffles a subset and creates a copy
|
|
def sample(population, k):
|
|
x = population.slice()
|
|
for i in range(population.length-1, population.length-k-1, -1):
|
|
j = Math.floor(random() * (i+1))
|
|
x[i], x[j] = x[j], x[i]
|
|
return x.slice(population.length-k)
|
|
|
|
|
|
#import stdlib
|
|
#a = range(50)
|
|
#random.seed(5)
|
|
#print(random.choice(a))
|
|
#print(random.shuffle(a))
|
|
#print(random.randrange(10))
|
|
#print(random.randint(1,5))
|
|
#print(random.uniform(1,5))
|
|
#print(random.sample(range(20),5))
|