Как отобразить код в Streamlit на основе ответа пользователя?

Я пытаюсь создать учебник для библиотеки с Streamlit. Моя общая идея состоит в том, чтобы пройтись по различным функциям и классам и объяснить их вместе с пользовательским вводом, чтобы все стало немного более понятным для новичков. Тем не менее, я написал 5 руководств ранее для более опытных пользователей и хотел бы повторно использовать часть этого кода, вызывая его из моего приложения и поддерживая его только один раз.

Кроме того, я прохожу через множество функций и классов, примеры файлов конфигурации, например. и я звоню им из диктофона.

Поскольку Streamlit предлагает с st.echo возможность запускать код, а затем отображать его, я пробовал это. Также я пытался использовать элемент python inspect вместе с st.write. Однако st.echo просто отображает имя функции, а st.write вместе с inspect просто отображает строку.


display_code = st.radio("Would you like to display the code?", ("Yes", "No"))

    if display_code == "Yes":
        with st.echo():
            example_function_1()



    else:
        example_function_1()

В основном я ищу возможность передать функцию и на основе пользовательского ввода просто запустить ее или запустить и отобразить код и комментарии к нему.

Таким образом, если пользователь выбрал «Да», будут возвращены выходные данные, а также x, y.

def example_function_1():
     """ 
     This is and example functions that is now displayed. 
     """ 
     Some Magic
     return x, y 

И если пользователь выбрал Нет, то возвращаются только x, y


person Hirschdude    schedule 26.02.2020    source источник


Ответы (2)


Вот модифицированная версия st.echo() Streamlit, которая включает флажок:

import contextlib
import textwrap
import traceback

import streamlit as st
from streamlit import source_util


@contextlib.contextmanager
def maybe_echo():
    if not st.checkbox("Show Code"):
        yield
        return

    code = st.empty()
    try:
        frame = traceback.extract_stack()[-3]
        filename, start_line = frame.filename, frame.lineno

        yield

        frame = traceback.extract_stack()[-3]
        end_line = frame.lineno
        lines_to_display = []
        with source_util.open_python_file(filename) as source_file:
            source_lines = source_file.readlines()
            lines_to_display.extend(source_lines[start_line:end_line])
            initial_spaces = st._SPACES_RE.match(lines_to_display[0]).end()
            for line in source_lines[end_line:]:
                indentation = st._SPACES_RE.match(line).end()
                # The != 1 is because we want to allow '\n' between sections.
                if indentation != 1 and indentation < initial_spaces:
                    break
                lines_to_display.append(line)
        lines_to_display = textwrap.dedent("".join(lines_to_display))

        code.code(lines_to_display, "python")

    except FileNotFoundError as err:
        code.warning("Unable to display code. %s" % err)

Вы можете использовать его точно так же, как st.echo. Например:

with maybe_echo():
    some_computation = "Hello, world!"
    st.write(some_computation)
person Tim Conkling    schedule 04.03.2020
comment
Я использовал флажок вместо радиогруппы, потому что есть только два варианта, но вы, конечно, можете изменить это, чтобы использовать st.radio. - person Tim Conkling; 04.03.2020

Вы можете использовать состояние сеанса для передачи пользовательского ввода в действия на экране. Наглядный пример с переключателями можно найти здесь . Вообще говоря, для этого вам нужно использовать st.write (). Упрощенный пример со слайдером:

import streamlit as st

x = st.slider('Select a value')
st.write(x, 'squared is', x * x)

То, что вы ищете, не совсем возможно, поскольку вам нужно указать функцию в блоке with st.echo (). Вы можете видеть это здесь:

import inspect
import streamlit as st

radio = st.radio(label="", options=["Yes", "No"])

if radio == "Yes":
    with st.echo():
        def another_function():
            pass
        # Print and execute function
        another_function()
elif radio == "No":
    # another_function is out of scope here..
    another_function()
person Nebulastic    schedule 26.02.2020
comment
Спасибо, но я знаю, как работать с пользовательским вводом. Мой вопрос заключается в том, как отобразить код внутри функции, основанной на нем, при этом код все еще выполняется. - person Hirschdude; 26.02.2020
comment
Вы имеете в виду, что хотите распечатать / повторить код функции? - person Nebulastic; 26.02.2020
comment
Точнее, я хотел бы вызвать функцию из другого модуля, одновременно выполняя и распечатывая ее. - person Hirschdude; 26.02.2020