diff --git a/bootstrap.py b/bootstrap.py new file mode 100644 index 0000000..4e5b751 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,8 @@ +# minimal one-file ota-bootstrap + +import usocket, ujson, os, time, gc, wifi + +# todo + +if __name__ == '__main__': + bootstrap() diff --git a/lib/homescreen.py b/lib/homescreen.py index e77d16c..a8ab84c 100644 --- a/lib/homescreen.py +++ b/lib/homescreen.py @@ -36,6 +36,8 @@ def init(enable_menu_button = True): buttons.enable_interrupt("BTN_MENU", lambda t: set_state("menu"), on_release = True) def set_state(key, value = True): + # we can't allocate memory in interrupts, so make sure all keys are set beforehand and + # you're only using numbers and booleans global _state _state[key] = value @@ -57,8 +59,8 @@ def name(default = None): return database.get("homescreen.name", default) def wifi_strength(): - return random.rand() / 256 + return random.random() def battery(): - return random.rand() / 256 + return random.random() diff --git a/lib/random.py b/lib/random.py index 6cf1493..23c57d5 100644 --- a/lib/random.py +++ b/lib/random.py @@ -1,9 +1,40 @@ -"""Library to generate random numbers""" +"""Library to generate random numbers + +Warning! Don't use this for anything important, it's probably biased +""" ___license___ = "MIT" import os -# todo: write an actual useful function -def rand(): - return int(os.urandom(1)[0]) +_bigrand_bytes = 10 +_bigrand_max = pow(256, _bigrand_bytes) + +def _bigrand(): + """generates a random number between 0 (incl) and _bigrand_max (excl)""" + base = 0 + for b in os.urandom(_bigrand_bytes): + base = (base << 8) + b + return base + +def random(): + """Return the next random floating point number in the range [0.0, 1.0).""" + return _bigrand() / _bigrand_max + +def randrange(start, stop=None): + """Return a randomly selected element from range(start, stop)""" + if stop is None: + stop = start + start = 0 + return start + (_bigrand() * (stop - start) // _bigrand_max) + +def randint(start, stop): + """Return a random integer N such that a <= N <= b.""" + return randrange(start, stop + 1) + +def shuffle(seq): + """Shuffle the sequence x in place.""" + l = len(seq) + for i in range(l): + j = randrange(l) + seq[i], seq[j] = seq[j], seq[i] diff --git a/lib/test_random.py b/lib/test_random.py index 2492a37..5402caa 100644 --- a/lib/test_random.py +++ b/lib/test_random.py @@ -8,12 +8,31 @@ from random import * class TestRandom(unittest.TestCase): - def test_rand(self): + def test_random(self): for i in range(1, 100): - r = rand() - self.assertTrue(r>0) - self.assertTrue(r<256) + r = random() + self.assertTrue(r>=0) + self.assertTrue(r<=1) + def test_randint(self): + for i in range(1, 100): + r = randint(500, 1000) + self.assertTrue(r>=500) + self.assertTrue(r<=1000) + + def test_randrange(self): + for i in range(1, 100): + r = randrange(10) + self.assertTrue(r>=0) + self.assertTrue(r<10) + + def test_shuffle(self): + for i in range(1, 100): + r = list(range(1, 10)) + shuffle(r) + self.assertEqual(sum(r), 45) + self.assertEqual(set(r), set(range(1, 10))) + self.assertNotEqual(r, list(range(1, 10))) if __name__ == '__main__':