Org Mode Babel - Valutazione interattiva del blocco di codice in Python


12

Analogamente a questa domanda, vorrei valutare (in modalità org) blocchi di codice sorgente Python contenenti istruzioni "input" ma non riesco a trovare un modo per avere una valutazione interattiva (con input dell'utente) durante la valutazione o per dargli un input noto in anticipo (memorizzato in un file per esempio).

Il mio vincolo è usare esplicitamente le inputistruzioni poiché tutto ciò dovrebbe essere incluso in un libro di testo per gli studenti.

Esempio di codice:

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

È possibile avere una valutazione così interattiva o simularla (dando al codice sorgente un input falso)?


Utilizzerai la modalità org exportper generare il tuo codice di esempio per gli studenti in un altro formato, ad esempio HTML?
Melioratus,

La funzione input () di Python accetta solo testo tra virgolette su una sola riga, ad es. "Ciao" o "ciao \ nhow \", giusto?
Melioratus,

@Melioratus Grazie per i tuoi commenti; sì Uso l'esportazione in modalità org (in LaTeX / pdf) e esporto sia il codice che il risultato. È inoltre possibile utilizzare il testo multilinea ("" "..." "") come parametro per la funzione di input. Il mio problema è introdurre valori nella funzione "input" durante l'esecuzione del codice.
Lgen,

Grazie per il chiarimento! Pubblicherò una risposta che utilizza le funzionalità di programmazione alfabetica, ovvero la nowebmodalità org che ti permetterà di testare ed esportare il tuo codice con i risultati.
Melioratus,

Grazie, questa potrebbe essere un'alternativa alla soluzione proposta da John Kitchin (potrebbe evitare il passo groviglio?).
Lgen,

Risposte:


8

Ecco un approccio alternativo che utilizza un file aggrovigliato non esportato per sostituire la funzione di input.

#+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: 

Suggerimento: premere C-cC-vto utilizzare il M-xorg-babel-tanglecomando per creare, ad esempio groviglio , il example1.pyfile.


#+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

Nota: il example1.pyfile creato dal precedente SRCblocco Python verrà importato nel blocco corrente usando l' intestazione preambolo incorporato e il valore from example1 import *.


Soluzione molto interessante, grazie. Lo accetto come soluzione e proporrò anche una variante basata sul generatore Python e restituendo sistematicamente un oggetto "str" ​​per imitare la funzione di input (...).
Lgen,

8

Valuta i pythonblocchi di codice usando la programmazione alfabetica in modalità org.

Usa l' :varintestazione per assegnare variabili e testare il tuo codice.

Nota: se lo si desidera, utilizzare elisp (read-string "Prompt: ")e (read-number "Prompt: ")per richiedere l'input dell'utente all'interno di emacs.


Esempio 1 - stampa (a)

  • Assegna hello worlda 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
    

Esempio 2 - print(a + b)

  • Assegna 1a a.

  • Assegna 2a 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
    

Esempio 3 - print(a,b,c)

  • Quando viene richiesto di Value of ainserireThanks
  • Quando viene richiesto di Value of binserire 4.
  • Quando viene richiesto di Value of cinserire 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
    

Quando esporti il ​​tuo file org, l'output dovrebbe essere simile all'esempio seguente


Esempio 1 - print(a)

  • Assegna hello worlda a.

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

Esempio 2 - print(a + b)

  • Assegna 1a a.
  • Assegna 2a b.

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

Esempio 3 - print(a,b,c)

  • Quando viene richiesto di Value of ainserireThanks
  • Quando viene richiesto di Value of binserire 4.
  • Quando viene richiesto di Value of cinserire 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
    


Questo codice è stato testato con
GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK + Versione 3.14.13) Versione
Org-Mode: 8.3.2
e github.


Soluzione molto interessante; mi ci è voluto del tempo per capire (non sono abituato a letterare la programmazione) che le istruzioni nel secondo blocco sorgente python (es. a = input ('Valore di a')) erano solo testo di documentazione e non venivano trattate come istruzioni.
Lgen,

@Lgen - Grazie! La programmazione alfabetica noweb, in modalità org-mode è sorprendente e incredibilmente utile! Per favore fatemi sapere se volete ulteriori esempi di codice. Se hai bisogno di qualcosa che non si adatta bene al formato Domande e risposte, sono felice di postare nel mio repository GitHub.
Melioratus,

6

Non penso che sia possibile ottenere input Python veramente interattivi con org-babel.

È possibile utilizzare un preambolo per ridefinire la funzione di input in modo che restituisca ciò che si desidera simulare l'uso dell'input, ad esempio qui lo facciamo sembrare come l'utente digitato "3".

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

#+RESULTS:
: 3

A seconda di ciò che gli studenti vedono che viene esportato, potrebbero non vedere che l'hai fatto.


Grazie John per la tua proposta di risposta. Mi chiedevo se fosse possibile estenderlo a una chiamata multipla alla funzione di input nel blocco di codice (ad es. A = input ("Valore di a") b = input ("Valore di b")). Per creare il libro di testo di solito uso e ": esporta entrambi" nell'istruzione "# + BEGIN_SRC python", quindi questa riga non dovrebbe essere visibile nel testo esportato.
Lgen,

Se si utilizza una sessione, è possibile: # + BEGIN_SRC python: sessione: non esporta alcun input def (x): se x == 'Valore di a': return 3 elif x == 'Valore di b': return 4 # + END_SRC # + RISULTATI: # + BEGIN_SRC python: output dei risultati: sessione a = input ('Valore di a') b = input ('Valore di b') stampa (a + b) # + END_SRC # + RISULTATI::: >>> >>> 7
John Kitchin,

2

Come complemento della soluzione di John Kitchin, propongo di utilizzare un generatore per fornire i valori successivi che "alimenteranno" le input(...)funzioni e restituiranno strsistematicamente un oggetto.

#+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 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.