Get help from the marimo community

Updated 5 months ago

Recommended way for self-triggering computation / semi-infinite loop?

Is there a recommended way to trigger a cell (which mutates state) to re-run after it's done -- under some conditions?

I was under the impression the following combination of switch/stop would do the trick, but it doesn't seem to be able to escape the infinite loop?

Plain Text
import marimo as mo
import random
import time


Plain Text
get_seconds, set_seconds = mo.state(1)


Plain Text
def expensive_computation():
    seconds = get_seconds()
    time.sleep(seconds)
    set_seconds(random.randint(1,3))


Plain Text
infinite_loop = mo.ui.switch(
    False,
    label="infinite loop",
)
infinite_loop

Plain Text
mo.stop(not infinite_loop.value)
expensive_computation()


My actual use-case (https://marimo.io/p/@gvarnavides/iterative-ptychography) is less contrived. Essentially I'd like to plot the output of an iterated map at every iteration. Right now, I'm doing it with mo.ui.refresh - which works well, but I'd like a "as quick as possible" update instead of fixed time-increments (since the computation time varies with batch_size).
M
G
A
13 comments
On set_state, I think there is an include_self flag you can pass
The refresh button has network latency and other latencies included so not great as an accurate timer
I played around with include_self and it doesn't seem to help (in-fact presumably the default False is designed to capture this infinite-loop behaviour?)
I think you can put get and set in the same cell and use include_self
Not sure that's the issue? like I can get set/get to loop infinitely just fine.
I just want a way to kill that once it's running. The following doesn't seem to work
Plain Text
mo.stop(not infinite_loop.value)
expensive_computation()


playground here: https://marimo.app/?slug=19s2hr
oh sorry I misunderstood. Hmm yea I’m not sure how to interrupt that
I wondered if the on_change parameter of the mo.ui.switch input could be used to emit some sort of event to break the set/get cycle, but not sure what that would be
Could you raise an error?
wow, that doesn't seem to bother it either haha
Plain Text
def raise_(val):
    if not val:
        raise ValueError()

infinite_loop = mo.ui.switch(
    False,
    label="infinite loop",
    on_change=lambda v: raise_(v)
)
hmm I have no other ideas. We can look into supporting this if there is a good api. Seems like start/stop has been somewhat tried a few times
@Georgios Varnavides can you use mo.output.replace?
hmm, trying to think how exactly 🤔
I'd still need to mutate state for the iteration of the sort x_{n+1} = f[x_n] right?
Recommended way for self-triggering computation / semi-infinite loop?
Add a reply
Sign up and join the conversation on Discord