I believe the issue is that you have to use methods compatible with asyncio
. While it may not be obvious at first glance, that await
comes from that part of the standard library. A for
loop is a synchronous loop and doesn’t inherently support asynchronous events in it.
Here are three options that give you something that works in JupyterLite. You’ll note it is much more complex because you cannot mix.
Option 1
%pip install ipywidgets
import numpy as np
import ipywidgets as widgets
from IPython.display import display
l = []
# Create output widget to show progress
output = widgets.Output()
display(output)
text_input = widgets.Text(description="Enter:")
counter = [0] # Using a list to allow modification in the callback
def on_submit(sender):
with output:
# Get the current value and add to list
l.append(text_input.value)
counter[0] += 1
print(f"Added: {text_input.value}")
text_input.value = "" # Clear the input
# Check if we have 4 inputs
if counter[0] >= 4:
print("\nAll inputs collected!")
print(f"Final list: {l}")
print(f"Type: {type(l)}")
print(f"NumPy array: {np.array(l)}")
text_input.layout.display = 'none' # Hide the input widget
else:
print(f"Please enter item {counter[0]+1}/4")
text_input.on_submit(on_submit) # Register the callback
# Display the input widget
print("Please enter item 1/4")
display(text_input)
That works in JupyterLite but a present I see this warning:
DeprecationWarning: on_submit is deprecated. Instead, set the .continuous_update attribute to False and observe the value changing with: mywidget.observe(callback, 'value').
text_input.on_submit(on_submit) # Register the callback
Option 2
This works in JupyterLite with no warning but adds a button to submit instead of relying on ‘Enter’:
%pip install ipywidgets
import numpy as np
import ipywidgets as widgets
from IPython.display import display
l = []
# Create output widget to show progress
output = widgets.Output()
text_input = widgets.Text(description="Enter:")
submit_button = widgets.Button(description="Submit")
counter = [0] # Using a list to allow modification in the callback
def on_button_click(b):
with output:
# Get the current value and add to list
value = text_input.value
if value: # Only add if there's something to add
l.append(value)
counter[0] += 1
print(f"Added: {value}")
text_input.value = "" # Clear the input
# Check if we have 4 inputs
if counter[0] >= 4:
print("\nAll inputs collected!")
print(f"Final list: {l}")
print(f"Type: {type(l)}")
print(f"NumPy array: {np.array(l)}")
text_input.layout.display = 'none' # Hide the input widget
submit_button.layout.display = 'none' # Hide the button
else:
print(f"Please enter item {counter[0]+1}/4")
submit_button.on_click(on_button_click) # Register the callback
# Display the widgets
print("Please enter item 1/4")
display(widgets.VBox([widgets.HBox([text_input, submit_button]), output]))
Option 3
Finally, if you are using ipywidgets to collect all the output, you can just prompt for each individual input at the start and hit a button once to go to the next step:
%pip install ipywidgets
import numpy as np
import ipywidgets as widgets
from IPython.display import display
# Create individual input fields
input1 = widgets.Text(description="Item 1:")
input2 = widgets.Text(description="Item 2:")
input3 = widgets.Text(description="Item 3:")
input4 = widgets.Text(description="Item 4:")
# Create the process button
process_button = widgets.Button(description="Process All Inputs")
# Create output area
output = widgets.Output()
def on_process_button_click(b):
with output:
# Clear previous output
output.clear_output()
# Collect all inputs
l = [input1.value, input2.value, input3.value, input4.value]
# Show results
print(f"Collected inputs: {l}")
print(f"Type: {type(l)}")
print(f"NumPy array: {np.array(l)}")
# Optionally, clear input fields
input1.value = ""
input2.value = ""
input3.value = ""
input4.value = ""
process_button.on_click(on_process_button_click) # Register the button callback
# Display all widgets in a vertical layout
display(widgets.VBox([
widgets.HTML("<h3>Enter 4 values:</h3>"),
input1,
input2,
input3,
input4,
process_button,
output
]))
Minor aside:
Please read Getting good answers to your questions. I would especially refer you to How do I ask a good question? referenced at the bottom. One of the ideas stressed in both of these is to make things easy for those trying to help you. One way to do that is to provide code formatted so that it can be used without further editing. To help you with that please learn about ‘block code formatting’ here. (Or see about ‘fenced code blocks’ here. They are both the same thing if you look into the details. They just have slightly different terms used in the two locations. And then one way to test things is to start a fresh JupyterLite session in incognito mode or private mode and then copy the code from your finished post and run it fresh. It should work to give what you expect and not unrelated errors.
I imagine the failure to do this contributed to a delay in responses by folks here.
For the record, this was the code provided in the original post formatted to actually be usable:
import numpy as np
l=[]
for i in range(1,5):
inp= await input("Enter:")
l.append(inp)
print(type(l))
print( np.array(l))