Org Mode Babel - Evaluasi blok kode interaktif dengan Python

12

Demikian pula dengan pertanyaan ini, saya ingin mengevaluasi (dalam mode org) blok kode sumber Python yang berisi instruksi "input" tetapi saya tidak dapat menemukan cara untuk melakukan evaluasi interaktif (dengan input pengguna) selama evaluasi atau untuk memberikannya beberapa input yang diketahui di muka (disimpan dalam file misalnya).

Kendala saya adalah menggunakan inputinstruksi secara eksplisit karena semua ini harus dimasukkan dalam buku teks untuk siswa.

Contoh kode:

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

Apakah mungkin untuk melakukan evaluasi interaktif atau mensimulasikannya (dengan memberikan kode sumber input palsu)?

Lgen
sumber
Apakah Anda akan menggunakan mode-org exportuntuk menghasilkan kode contoh Anda untuk siswa ke dalam format lain, misalnya html?
Melioratus
Fungsi input () Python hanya mengambil teks yang dikutip dalam satu baris, misalnya "halo" atau "hi \ nhello \ nhowdy", benar?
Melioratus
@Melioratus Thaks untuk Anda komentar; ya saya menggunakan ekspor mode-org (ke LaTeX / pdf) dan saya mengekspor kode dan hasilnya. Anda juga dapat menggunakan teks multiline ("" "..." "") sebagai parameter untuk fungsi input. Masalah saya adalah untuk memperkenalkan nilai pada fungsi "input" selama eksekusi kode.
Lgen
Terimakasih atas klarifikasinya! Saya akan memposting jawaban yang menggunakan fitur pemrograman literasi, yaitu nowebmode-org yang memungkinkan Anda menguji & mengekspor kode Anda dengan hasil.
Melioratus
Terima kasih, ini bisa menjadi alternatif untuk solusi yang diusulkan oleh John Kitchin (mungkin menghindari langkah kusut?).
Lgen

Jawaban:

8

Berikut adalah pendekatan alternatif yang menggunakan file kusut yang tidak diekspor untuk menggantikan fungsi 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: 

Tip: Tekan C-cC-vtatau gunakan M-xorg-babel-tangleperintah untuk membuat, yaitu kusut , 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

Catatan: The example1.pyfile yang diciptakan dari python sebelumnya SRCblok akan diimpor ke blok saat menggunakan builtin yang : Pembukaan header dan nilai from example1 import *.

John Kitchin
sumber
Solusi yang sangat menarik, terima kasih. Saya menerimanya sebagai solusi dan saya juga akan mengusulkan varian berdasarkan generator python dan mengembalikan secara sistematis objek "str" ​​untuk meniru fungsi input (...).
Lgen
8

Mengevaluasi pythonblok kode menggunakan pemrograman melek huruf dalam mode-org.

Gunakan :vartajuk untuk menetapkan variabel dan menguji kode Anda.

Catatan: Jika diinginkan, gunakan elisp (read-string "Prompt: ")dan (read-number "Prompt: ")untuk meminta input pengguna di dalam emacs.


Contoh 1 - cetak (a)

  • Tetapkan hello worlduntuk 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
    

Contoh 2 - print(a + b)

  • Tetapkan 1untuk a.

  • Tetapkan 2untuk 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
    

Contoh 3 - print(a,b,c)

  • Ketika diminta untuk Value of amasukThanks
  • Ketika diminta untuk Value of bmasuk 4.
  • Ketika diminta untuk Value of cmasuk 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
    

Ketika Anda mengekspor file org Anda, hasilnya akan terlihat mirip dengan contoh di bawah ini


Contoh 1 - print(a)

  • Tetapkan hello worlduntuk a.

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

Contoh 2 - print(a + b)

  • Tetapkan 1untuk a.
  • Tetapkan 2untuk b.

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

Contoh 3 - print(a,b,c)

  • Ketika diminta untuk Value of amasukThanks
  • Ketika diminta untuk Value of bmasuk 4.
  • Ketika diminta untuk Value of cmasuk 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
    


Kode ini diuji dengan
GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK + Versi 3.14.13) Versi
Org-Mode: 8.3.2
dan github.

Melioratus
sumber
Solusi yang sangat menarik; butuh waktu bagi saya untuk memahami (saya tidak terbiasa melek pemrograman) bahwa instruksi dalam blok sumber python kedua (misalnya a = input ('Nilai a')) hanya teks dokumentasi dan tidak diperlakukan sebagai instruksi.
Lgen
@Lgen - Terima kasih! Pemrograman melek huruf noweb,, dalam fitur mode-org luar biasa dan sangat berguna! Harap beri tahu saya jika Anda ingin contoh kode tambahan. Jika Anda membutuhkan sesuatu yang tidak sesuai dengan format T&J, saya senang memposting ke repositori GitHub saya.
Melioratus
6

Saya tidak berpikir itu mungkin untuk mendapatkan input Python benar-benar interaktif dengan org-babel.

Anda bisa menggunakan pembukaan untuk mendefinisikan kembali fungsi input sehingga mengembalikan apa yang Anda inginkan untuk mensimulasikan penggunaan input, misalnya di sini kita membuatnya tampak seperti pengguna mengetikkan "3".

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

#+RESULTS:
: 3

Bergantung pada apa yang siswa lihat yang diekspor, mereka mungkin tidak melihat bahwa Anda telah melakukan ini.

John Kitchin
sumber
Terima kasih John atas jawaban yang Anda usulkan. Saya bertanya-tanya apakah mungkin untuk memperpanjangnya ke beberapa panggilan ke fungsi input dalam blok kode (misalnya a = input ("Nilai a") b = input ("Nilai b")). Untuk membangun texbook yang biasanya saya gunakan dan ": ekspor keduanya" dalam pernyataan "# + BEGIN_SRC python" sehingga baris ini tidak akan terlihat dalam teks yang diekspor.
Lgen
Jika Anda menggunakan suatu sesi, itu dimungkinkan: # + BEGIN_SRC python: session: mengekspor tidak ada input def (x): jika x == 'Nilai a': return 3 elif x == 'Nilai b': return 4 # + END_SRC # + HASIL: # + BEGIN_SRC python: hasil keluaran: sesi a = input ('Nilai a') b = input ('Nilai b') cetak (a + b) # + END_SRC # + HASUL::: >>> >>> 7
John Kitchin
2

Sebagai pelengkap dari solusi John Kitchin, saya mengusulkan untuk menggunakan generator untuk memberikan nilai-nilai berturut-turut yang akan "memberi makan" input(...)fungsi dan mengembalikan strobjek secara sistematis.

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