0

From a PyScript app, I am providing two radio buttons in my index.html, allowing a user to decide wether synthesis of isotropic gaussian blobs should be overlapping or not (effectively by toggling the value of Scikit-Learn's cluster_std value for the make_blobs method).

app reference: https://24ec0d6b-0b55-49be-aeb7-a0046c41abf4.pyscriptapps.com/ea775901-75b9-406d-beac-944d26301b09/latest/

I am currently unable to parse the choice into Python booleans (True or False) and always receive a True value regardless of which radio button that was clicked.

Experimented a bit with defining the values in HTML as double-, single-, or un-quoted as well as switching between different casings (titled, upper, lower) without luck. Also had a look at other examples/questions here on SO, e.g. How to pass a boolean from javascript to python?

Snippet from the relevant section in the HTML:

<div id="input" style="margin: 20px;">
  Should the clusters overlap: <br/>
  <input py-click="generate_blobs()" type="radio" id="true" name="overlaps" value="true">
  <label for="true"> True</label>
  <input py-click="generate_blobs()" type="radio" id="false" name="overlaps" value="false">
  <label for="false"> False</label>
</div>

And similarly for the Python snippet:

def generate_blobs():
    """Generate isotropic Gaussian blobs for clustering"""

    over_laps = js.document.getElementsByName("overlaps")
    for element in over_laps:
        if element.checked:
            overlap = bool(element.value)

            print(overlap, type(overlap))
            
            break
    paragraph = Element("Overlap")
    paragraph.write(f"overlaps: {overlap}")

    n_samples = 4_000  # if overlap else 2_000
    cluster_std = 1.5 if overlap else .4

    X, y = datasets.make_blobs(
            n_samples = n_samples,
            n_features = 2,
            centers = 5,
            cluster_std = cluster_std,
            shuffle = True,
        )

    return X, y

Result from setting the False option:

radio button choice: false

Any suggestions are most welcome as I am running out of ideas to try

0

1 Answer 1

1

Your issue is caused by using py-click.

py-click is not able to pass the click-event from Javascript.


Consider using addEventListener to the result of js.document.querySelectorAll, this way you'll get the event which you can use to get the value

Don't forget to wrap your function in create_proxy to ensure it's removed when needed.


Small example:

.as-console-wrapper { max-height: 45px !important; }
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title></title>
        <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
        <script defer src="https://pyscript.net/latest/pyscript.js"></script>
    </head>
    <body>
        <div id="input" style="margin: 20px;">
            Should the clusters overlap: <br/>
            <input type="radio" id="true" name="overlaps" value="true">
            <label for="true"> True</label>
            <input type="radio" id="false" name="overlaps" value="false">
            <label for="false"> False</label>
        </div>
        <py-script>
            from pyodide.ffi import create_proxy

            def onInputClick(e):
                elementId = e.target.id
                elementValue = e.target.value

                print(f"Clicked on <{elementId}>, new value: <{elementValue}>")

            for i in js.document.querySelectorAll('input'):
                i.addEventListener("click", create_proxy(onInputClick))
        </py-script>
    </body>
</html>

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you @0stone0 for the fast answering. I have added your suggestion, and now the result changes from True to False, in the displayed value. Doesn't affect the graph yet for some reason, did I perhaps miss some detail? (wasn't sure where to add the .as-console-wrapper { max-height: 45px !important; }). (Upvoted your answer)
The css included is just to format the stackoverflow snippet. You won't need that. Not sure why your graph is not effected. If you could include an minimal reproducible example to your question it would be easier to help you with that.
Thanks for clarifying wrt the CSS. I have updated the app with your suggestion: 24ec0d6b-0b55-49be-aeb7-a0046c41abf4.pyscriptapps.com/… yet something still hinders the graph from taking selected effect wrt the overlap choice..
This is a good answer. One further thing you could use - the Pyodide ffi includes some functionality that handles proxy wrapping for the user, as well as tracking proxies that have been assigned, as from pyodide.ffi.wrappers import add_event_listener. So you can do for i in js.document.querySelectorAll('input'): add_event_listener(i, "click", onInputClick)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.