Input Function Not Working

The main examples for Jupyter Notebook and JupyterLab used to use MyBinder-served sessions but it was too taxing on the MyBinder system and when JupyterLite came along it was seen as a way to let users ‘try’ the interface without needing to run a remote machine.

From the ‘Try Jupyter’ page, you can still use MyBinder-served sessions. If you hover over some of the other tiles like Voila and the ones under ‘Kernels’, towards the bottom of the page there. The easiest one to use an ipykernel there is to click on the ‘Julia’ tile to launch that example and when the session comes up, switch the kernel to the ipykernel using ‘Kernel’ > ‘Change Kernel’ > ‘Python 3 (ipykernel)’ from the File menubar along the top. The Voila one isn’t easy to switch out of the Voila rendering although it is possible to get to Jupyter from there using the URL.

Alternative to input() that works in JupyterLite/pyodide

OP’s code can be written like this below to use ipywidgets to let the user guess the number and that works in JupyterLite / Pyodide because ipywidgets work in JupyterLite:

import ipywidgets as widgets
from IPython.display import HTML
import random

secret = random.randint(1, 10)
guessed_correctly = False

slider = widgets.IntSlider(
    value=0,
    max= 10,
    description='Slide to Your Guess:',
    continuous_update=False,
    style= {'description_width': 'initial'},
)


def on_value_change(change):
    global guessed_correctly
    if not guessed_correctly:
        if slider.value == secret:
            guessed_correctly = True
            output.update(HTML("You got it!"))
        else:
            output.update(HTML("Too small" if slider.value < secret else "Too big"))


output = display(HTML("The secret number is a number between 1 and 10.<br>Click and drag the slider from zero to your guess and then release the mouse button to submit your guess."), display_id=True)
display(slider)

slider.observe(on_value_change, names='value')

Importantly, besides working in JupyterLite / pyodide that can be customized extensively and is more functionally polished, modern, & interactive from the get-go than the legacy console-based input() method. Perhaps even more important for developing code in the Jupyter ecosystem is that same code will be useable in both a typical, full Python kernel (ipykernel) and pyodide, where ipywidgets as been installed. Below I provide more details about that and a place to run it in JupyterLite right now. (Currently ipywidgets was having an issue in the stable branch of JupyterLite, yet a fixed version is available.)

An alternative implementation using ipywidgets to enter the guesses with a reset button is in a gist here and that works in JupyterLite / Pyodide because ipywidgets work in JupyterLite. Below is a version of using ipywidgets to enter the guesses without the reset button because things are less complex, yet still fairly complex compared to the initial-input() based example and so I thought another step above the simpler version above would be informative to see the progression. Both are based on here primarily with some extras from here, because ipywidgets function in JupyterLite. (At present you can try it with ipywidgets in JupyterLite by clicking here and when that session comes up open a new notebook, let the busy indicator in the the upper right go to not busy, and then run %pip install -q ipywidgets in a cell followed by the code examples here. You have to use that version of JupyterLite for now because ipywidgets isn’t installing in the stable JupyterLite correctly at this time. That is temporary and will eventually be fixed on the main, stable branch, too.):

import ipywidgets as widgets

import random
max_secret = 10
secret = random.randint(1, max_secret)
guesses_allowed = 3
guesses_made = 0
game_still_going = True

# to leave out the quotes around strings sent to `ouptut.update()`, based on
# https://stackoverflow.com/a/70130979/8508004
class printer(str):
    def __repr__(self):
       return self

slider = widgets.IntSlider(
    value=0,
    min=0,
    max= max_secret,
    step=1,
    description='Slide to Your Guess:',
    disabled=False,
    continuous_update=False,
    orientation='horizontal',
    style= {'description_width': 'initial'},
    readout=True,
    readout_format='d'
)


def on_value_change(change):
    global guesses_allowed
    global guesses_made
    global game_still_going
    if game_still_going and (guesses_made < guesses_allowed - 1):
        guesses_made += 1
        if slider.value == secret:
            game_still_going = False
            output.update(printer(f'You win!\nYou guessed on your guess #{guesses_made} the number ' + str(slider.value) + f". The secret is: {secret}!\nRun the cell above to see if you are so lucky next time." ))
        else:
            output.update(printer(f"Guess #{guesses_made}:\nToo small" if slider.value < secret else f"Guess #{guesses_made}:\nToo big"))
    elif game_still_going:
        if slider.value == secret:
            game_still_going = False
            output.update(printer(f'You win!\nOn the last of your {guesses_allowed} guesses, you guessed ' + str(slider.value) + f"! The secret was: {secret}" ))
            
        else:
            game_still_going = False
            output.update(printer(f'Sorry. You lose!\nYou failed to guess the number in {guesses_allowed} guesses. Your last guess was ' + str(slider.value) + f". The secret was: {secret}\nRun the cell above to try the guessing game again." ))
    else:
        output.update(printer("THE GAME ENDED ALREADY.\nRun the cell above to try the guessing game again." ))

output = display(printer(f"The secret number is a number between 1 and {max_secret}.\nClick and drag the slider from zero to your guess and then release the mouse button to submit your guess.\nYou have three tries. You'll get a hint after each wrong guess."), display_id=True)
display(slider)

slider.observe(on_value_change, names='value')


IDEA THAT WAS-IN-PROGRESS (NOT WORKING YET!):
I was working on working this out having a timer without input() by using ipywidgets, like here:

import ipywidgets as widgets
import asyncio

import random
secret = random.randint(0, 10)
guesses_allowed = 3
# asyncio guess based on https://discourse.jupyter.org/t/is-it-possible-to-get-the-current-value-of-a-widget-slider-from-a-function-without-using-multithreading/15524/2?u=fomightez
slider = widgets.IntSlider(
    value=0,
    min=0,
    max=10,
    step=1,
    description='Your Guess:',
    disabled=False,
    continuous_update=False,
    orientation='horizontal',
    style= {'description_width': 'initial'},
    readout=True,
    readout_format='d'
)

async def select_guess(slider, output):
    i = 0
    while (i < guesses_allowed + 1):
        i = i+1
        if slider.value == secret:
            output.update('DONE ' + str(slider.value) + f" secret was: {secret}" )
        else:
            output.update(f"Guess #{i} (Secret:{secret}): Too small" if slider.value < secret else "Too big")
        await asyncio.sleep(5.1)
        #output.update(f"Guess #{i}: Too small" if slider.value < secret else "Too big")

output = display("Click and drag the slider to your guess and then release the mouse button to submit your guess. You have three tries. You get a hint after each wrong guess.", display_id=True)
display(slider)

asyncio.create_task(select_guess(slider, output));