【问题标题】:Using ipywidget for multiple choice test使用 ipywidget 进行多项选择测试
【发布时间】:2016-03-03 03:34:08
【问题描述】:

我对 python 和 python 笔记本还很陌生。我正在尝试创建一个 Jupyter 笔记本,它将显示图像列表中的图像,并为用户提供 4 个选项来选择可点击的 ipywidget 按钮中的图像。一旦用户单击他们的选择,我想用新图像替换图像并用 4 个新选择重新填充按钮。

我知道如何使用 button.close() 清除图像输出并关闭按钮小部件,但我似乎不知道如何使用新选项重新绘制按钮。一旦我关闭了容器,我就无法弄清楚如何循环回到顶部,因为一旦做出选择,我就会被困在 on_button_clicked 函数中。这是我到目前为止所拥有的,尽管我知道它还没有在工作附近,而且它可能在方法上很遥远。注意我不需要使用 ipywidgets,但从可点击按钮的角度来看,它似乎是一个不错的选择:

x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg']

choices = random.sample(x, 4)
correct = random.choice(choices)

display(Image(correct))
time.sleep(3)

button1 = widgets.Button(description = x[0])
button2 = widgets.Button(description = x[1])
button3 = widgets.Button(description = x[2])
button4 = widgets.Button(description = x[3])

container = widgets.HBox(children=[button1,button2,button3,button4])
display(container)


button1.on_click(on_button1_clicked)
button2.on_click(on_button2_clicked)
button3.on_click(on_button3_clicked)
button4.on_click(on_button4_clicked)


def on_button1_clicked(b):
     # [insert code to record choice] 
    container.close()
    clear_output()

def on_button2_clicked(b):
     # [insert code to record choice] 
    container.close()
    clear_output()

def on_button3_clicked(b):
     # [insert code to record choice] 
    container.close()
    clear_output()

def on_button4_clicked(b):
     # [insert code to record choice] 
    container.close()
    clear_output()

非常感谢!

【问题讨论】:

  • 您还应该包含您的导入语句!您是否考虑过在满足条件后使用breaks 的while 循环?

标签: python jupyter jupyter-notebook ipywidgets


【解决方案1】:

如果我了解您想要做什么,您可以将所有内容放入一个单独的函数中,并在每次单击按钮时调用它:

import random
import time
from IPython.display import Image, display, clear_output
from ipywidgets import widgets

x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg']

def redraw():
    choices = random.sample(x, 4)
    correct = random.choice(choices)

    display(Image(correct))
    time.sleep(3)

    button1 = widgets.Button(description = choices[0])
    button2 = widgets.Button(description = choices[1])
    button3 = widgets.Button(description = choices[2])
    button4 = widgets.Button(description = choices[3])

    container = widgets.HBox(children=[button1,button2,button3,button4])
    display(container)

    def on_button1_clicked(b):
        # [insert code to record choice] 
        container.close()
        clear_output()
        redraw()

    def on_button2_clicked(b):
        # [insert code to record choice] 
        container.close()
        clear_output()
        redraw()

    def on_button3_clicked(b):
        # [insert code to record choice] 
        container.close()
        clear_output()
        redraw()

    def on_button4_clicked(b):
        # [insert code to record choice] 
        container.close()
        clear_output()
        redraw()

    button1.on_click(on_button1_clicked)
    button2.on_click(on_button2_clicked)
    button3.on_click(on_button3_clicked)
    button4.on_click(on_button4_clicked)

redraw() # initializes the first choice

一些cmets:

  • 我想在你想要的按钮的描述中 您选择的 4 个样本中的文本(即来自 choices)不是 列表x 的前四个元素(因为它们不会改变)。
  • 您可能不想将选项数硬编码为 4,因为这样您就硬编码了 4 个按钮和 4 个按钮功能等。您可能希望根据所需的选项数生成按钮列表。比如:

    nchoices = 4
    x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg']
    
    def redraw():    
        choices = random.sample(x, nchoices)
        correct = random.choice(choices)
    
        display(Image(correct))
        time.sleep(3)
    
        buttons = [widgets.Button(description = choice) for choice in choices]
    
        container = widgets.HBox(children=buttons)
        display(container)
    
        def on_button_clicked(b):
            # [insert code to record choice]
            container.close()
            clear_output()
            redraw()
    
        for button in buttons:
            button.on_click(on_button_clicked)
    
    redraw()
    

    节省了大约一半的代码。

  • 我不知道您想通过单击按钮对选择做什么,但我可以想象您想比较 choicecorrect 并随后使用该信息做一些事情。您可以简单地通过b.description == correct 进行比较,如果条件为True'red',则建议为按钮'green' 着色,否则如下所示:

    def on_button_clicked(b):
        choice = b.description
        b.color = 'white'
        b.background_color = 'green' if choice == correct else 'red'
        time.sleep(5)
        container.close()
        clear_output()
        redraw()
    

【讨论】:

  • 工作就像一个魅力!太感谢了!我不知道像 on_button_clicked(b) 这样的函数内部的函数可以调用父函数 redraw()。这对理解非常有用。
  • @Snapula - 欢迎您!它是recursion 的一种类型,适用于这种情况。确实非常有用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多