Org Mode Babel - Інтерактивна оцінка кодового блоку в Python


12

Аналогічно цьому питанню, я хотів би оцінити (в режимі org) блоки вихідного коду Python, що містять "вхідні" інструкції, але я не можу знайти інтерактивну оцінку (із введенням користувача) під час оцінювання або дати їй деякий вхід відомий заздалегідь (наприклад, зберігається у файлі).

Моє обмеження полягає в тому, щоб явно використовувати inputінструкцію, оскільки все це повинно бути включено до підручника для студентів.

Приклад коду:

#+BEGIN_SRC python :results output 
a= input("Value") 
print(a)
#+END_SRC

Чи можливо мати таку інтерактивну оцінку чи змоделювати її (надаючи вихідному коду підроблений вклад)?


Чи будете ви використовувати org-режим exportдля створення вашого прикладу коду для студентів у якомусь іншому форматі, наприклад, html?
Меліорат

Функція input () Python приймає лише цитований текст у одному рядку, наприклад "привіт" чи "привіт \ nhello \ nhowdy", правильно?
Меліорат

@Melioratus Такси за ваші коментарі; так, я використовую експорт у режим org (у LaTeX / pdf) та експортую і код, і результат. Ви також можете використовувати багатомовний текст ("" "..." "") як параметр для функції введення. Моя проблема полягає в тому, щоб ввести значення функції "введення" під час виконання коду.
Lgen

Дякуємо за роз’яснення! Я опублікую відповідь, в якій використовуються грамотні функції програмування, тобто nowebв org-режимі, що дозволить вам протестувати та експортувати код з результатами.
Меліорат

Дякую, це може бути альтернативою рішенню, запропонованому Джоном Кітчіном (можливо, уникнути заплутаного кроку?).
Lgen

Відповіді:


8

Ось альтернативний підхід, який використовує неекспортований, заплутаний файл для заміни функції введення.

#+BEGIN_SRC python :session :exports none :tangle example1.py
def input(x): 
    if x == 'Value of a':
        return 3
    elif x == 'Value of b':
        return 4 

#+END_SRC 

#+RESULTS: 

Підказка: Натисніть кнопку C-cC-vtабо використовувати M-xorg-babel-tangleкоманду для створення, тобто переплетення , в example1.pyфайл.


#+BEGIN_SRC python :results output :preamble from example1 import *
a = input('Value of a')
b = input('Value of b')
print(a + b) 
#+END_SRC 

#+RESULTS:
: 7

Примітка . example1.pyФайл, створений з попереднього SRCблоку python, буде імпортований у поточний блок за допомогою заголовка вбудований : преамбула та значення from example1 import *.


Дуже цікаве рішення, дякую. Я приймаю це як рішення, а також запропоную варіант, заснований на генераторі пітона та систематично повертає об'єкт "str" ​​для імітації функції входу (...).
Lgen

8

Оцінюйте pythonкодові блоки за допомогою грамотного програмування в org-режимі.

Використовуйте :varзаголовок, щоб призначити змінні та протестувати свій код.

Примітка. За бажанням скористайтеся elisp (read-string "Prompt: ")та (read-number "Prompt: ")підкажіть для введення користувача всередині emacs.


Приклад 1 - print (a)

  • Призначають hello worldв a.


    #+name: ex1-code  
    #+header: :var a="hello world"  
    #+begin_src python :results verbatim replace output :exports results  
      print(a)  
    #+end_src
    
    #+begin_src python :eval never :exports code :noweb yes   
      a = input('Value of a')  
      <<ex1-code>>  
    #+end_src  
    
    #+results: ex1-code
    : hello world
    

Приклад 2 - print(a + b)

  • Призначають 1в a.

  • Призначають 2в b.


    #+name: ex2-code
    #+header: :var a=1 
    #+header: :var b=2 
    #+begin_src python :results replace output  :exports results 
      print(a + b)
    #+end_src
    
    #+begin_src python :eval never :exports code :noweb yes 
      a = input('Value of a')
      b = input('Value of b')
      <<ex2-code>>
    #+end_src  
    
    #+results: ex2-code
    : 3
    

Приклад 3 - print(a,b,c)

  • Коли буде запропоновано Value of aввестиThanks
  • Коли буде запропоновано Value of bввести 4.
  • Коли буде запропоновано Value of cввести your question.


    #+NAME: ex3-code
    #+header: :var a=(read-string "Value of a ") 
    #+header: :var b=(read-number "Value of b ") 
    #+header: :var c=(read-string "Value of c ") 
    #+begin_src python :results replace output   :exports results 
      print a,b,c
    #+end_src  
    
    #+begin_src python :eval never :exports code :noweb yes 
      a = input('Value of a')
      b = input('Value of b')
      c = input('Value of c')
      <<ex3-code>>
    #+end_src  
    
    #+results: ex3-code
    : Thanks 4 your question
    

Коли ви експортуєте файл org, вихід повинен виглядати аналогічно прикладу нижче


Приклад 1 - print(a)

  • Призначають hello worldв a.

    a = input('Value of a')
    print(a)
    
    hello world
    

Приклад 2 - print(a + b)

  • Призначають 1в a.
  • Призначають 2в b.

    a = input('Value of a')
    b = input('Value of b')
    print(a + b)
    
    3
    

Приклад 3 - print(a,b,c)

  • Коли буде запропоновано Value of aввестиThanks
  • Коли буде запропоновано Value of bввести 4.
  • Коли буде запропоновано Value of cввести your question.

    a = input('Value of a')
    b = input('Value of b')
    c = input('Value of c')
    print a,b,c
    
    Thanks 4 your question
    


Цей код був протестований за допомогою
GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK + Version 3.14.13) Версія для
Org-Mode: 8.3.2
та github.


Дуже цікаве рішення; мені знадобився час, щоб я зрозумів (я не звик грамотно програмувати), що вказівки у другому блоці джерела python (наприклад, a = input ('Value of a')) були лише текстом документації і не розглядалися як інструкції.
Lgen

@Lgen - Дякую! Грамотне програмування, nowebв org-режимі, функції дивовижні та неймовірно корисні! Будь ласка, дайте мені знати, якщо ви хочете отримати додаткові приклади коду. Якщо вам потрібно щось, що не добре вписується у формат запитань, я з радістю розміщу в моєму сховищі GitHub.
Меліорат

6

Я не думаю, що можна отримати справді інтерактивний вклад Python за допомогою org-babel.

Ви можете використовувати преамбулу, щоб переосмислити функцію введення, щоб вона повертала те, що ви хочете імітувати використання вводу, наприклад, тут ми робимо це схожим на користувача, введеного у "3".

#+BEGIN_SRC python :results output :preamble def input(x): return 3
a = input("value ")
print(a)
#+END_SRC

#+RESULTS:
: 3

Залежно від того, що студенти бачать, що експортується, вони можуть не бачити, що ви це зробили.


Дякую, Джон, що ти запропонував відповідь. Мені було цікаво, чи можна поширити його на багаторазовий виклик до функції введення в кодовому блоці (наприклад, а = вхід ("Значення a") b = вхід ("Значення b")). Для побудови підручника я зазвичай використовую та ": експортуйте обидва" у "# + BEGIN_SRC python", тому цей рядок не повинен бути видимим у експортованому тексті.
Lgen

Якщо ви використовуєте сеанс, можливо: # + BEGIN_SRC python: session: експортує жодний def вхід (x): якщо x == 'Значення a': повернути 3 elif x == 'Значення b': return 4 # + END_SRC # + РЕЗУЛЬТАТИ: # + BEGIN_SRC python: результат виведення: сеанс a = вхід ('Значення a') b = вхід ('Значення b') print (a + b) # + END_SRC # + РЕЗУЛЬТАТИ::: >>> >>> 7
Джон Кітчін

2

Як доповнення рішення Джона Кітчіна, я пропоную використовувати генератор для надання послідовних значень, які будуть "живити" input(...)функції та strсистематично повертати об'єкт.

#+BEGIN_SRC python :session :exports none :tangle example2.py :results none
def generate(lst):
    for element in lst:
        yield str(element)

generator =  generate(["Thanks",4,"your help"])

def input(x):
     return generator.__next__()
#+END_SRC 


#+BEGIN_SRC python :results output :preamble from example2 import * :exports both
a = input('Value of a')
b = input('Value of b')
c = input('Value of c')
print(a,b,c)
#+END_SRC 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.