Org Mode Babel - Python'da etkileşimli kod bloğu değerlendirmesi


12

Bu soruya benzer şekilde " org modunda" "girdi" talimatları içeren Python kaynak kodu bloklarını değerlendirmek istiyorum ancak değerlendirme sırasında etkileşimli bir değerlendirme (kullanıcı girdisi ile) elde etmenin ya da bilinen bir girdi vermenin bir yolunu bulamıyorum önceden (örneğin bir dosyada saklanır).

Benim kısıtlamam inputtalimatı açıkça kullanmaktır, çünkü tüm bunlar öğrenciler için bir ders kitabına dahil edilmelidir.

Kod örneği:

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

Böyle etkileşimli bir değerlendirme yapmak veya simüle etmek (kaynak koduna sahte bir giriş vererek) mümkün mü?


exportÖğrenciler için örnek kodunuzu başka bir formatta (ör. Html) oluşturmak için kuruluş modunu mu kullanacaksınız?
Melioratus

Python'un input () işlevi yalnızca tek satırda alıntılanan metni alır, örn. "Merhaba" veya "hi \ nhello \ nhowdy", doğru mu?
Melioratus

@Melioratus Görüşleriniz için teşekkürler; evet (LaTeX / pdf'ye) org-mode dışa aktarma kullanıyorum ve hem kodu hem de sonucu dışa aktarıyorum. Ayrıca, giriş işlevi için parametre olarak çok satırlı ("" "..." "") metin de kullanabilirsiniz. Benim sorunum kodun yürütülmesi sırasında "giriş" işlevine değerleri tanıtmaktır.
Lgen

Açıklama için teşekkürler! nowebKodunuzu test etmenizi ve sonuçlarla dışa aktarmanızı sağlayacak org modunun okuryazar programlama özelliklerini kullanan bir cevap göndereceğim.
Melioratus

Teşekkürler, bu John Kitchin tarafından önerilen çözüme bir alternatif olabilir (karışıklık adımından kaçıyor olabilir?).
Lgen

Yanıtlar:


8

Burada, giriş işlevini değiştirmek için dışa aktarılmamış, karışık bir dosya kullanan alternatif bir yaklaşım vardır.

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

İpucu: Basın C-cC-vtveya kullanmak M-xorg-babel-tangle, yani yaratma komutu arapsaçı , example1.pydosyayı.


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

Not:example1.py Bir önceki piton oluşturuldu dosya SRCbloğu yerleşiğini kullanılarak mevcut bloğun aktarılacak önsöz: başlık ve değeri from example1 import *.


Çok ilginç bir çözüm, teşekkürler. Ben çözüm olarak kabul ve ben de python jeneratör ve sistematik bir giriş (...) işlevini taklit etmek için bir "str" ​​nesnesi dönen bir değişken önerecektir.
Lgen

8

Kuruluş pythonmodunda okuryazar programlama kullanarak kod bloklarını değerlendirin .

:varDeğişkenleri atamak ve kodunuzu test etmek için başlığı kullanın .

Not: İstenirse kullanın elisp (read-string "Prompt: ")ve (read-number "Prompt: ")emacs içinde kullanıcı girişi istemek için kullanın .


Örnek 1 - Yazdır (a)

  • Ata hello worldiçin 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
    

Örnek 2 - print(a + b)

  • Ata 1için a.

  • Ata 2için 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
    

Örnek 3 - print(a,b,c)

  • İstendiğinde Value of agirmekThanks
  • İstendiğinde Value of bgirmek 4.
  • İstendiğinde Value of cgirmek 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
    

Kuruluş dosyanızı dışa aktardığınızda, çıktı aşağıdaki örneğe benzer olmalıdır


Örnek 1 - print(a)

  • Ata hello worldiçin a.

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

Örnek 2 - print(a + b)

  • Ata 1için a.
  • Ata 2için b.

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

Örnek 3 - print(a,b,c)

  • İstendiğinde Value of agirmekThanks
  • İstendiğinde Value of bgirmek 4.
  • İstendiğinde Value of cgirmek 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
    


Bu kod
GNU Emacs 24.5.1 (x86_64-bilinmeyen-cygwin, GTK + Sürüm 3.14.13)
Kuruluş Modu Sürümü: 8.3.2
ve github ile test edilmiştir .


Çok ilginç bir çözüm; ikinci python kaynak bloğundaki (örn. a = input ('a değeri)') talimatların sadece dokümantasyon metni olduğunu ve talimat olarak değerlendirilmediğini anlamam (programlama okurcasına alışkın değilim) zamanımı aldı.
Lgen

@Lgen - Teşekkürler! nowebOrg modundaki okuryazar programlama, şaşırtıcı ve inanılmaz derecede faydalı! Ek kod örnekleri isterseniz lütfen bize bildirin. Soru-Cevap formatına tam uymayan bir şeye ihtiyacınız varsa GitHub veri havuzuma göndermekten mutluluk duyarım.
Melioratus

6

Org-babel ile gerçekten etkileşimli Python girişi elde etmenin mümkün olduğunu düşünmüyorum.

Giriş işlevini yeniden tanımlamak için bir giriş kullanabilirsiniz, böylece giriş kullanımını simüle etmek istediğiniz şeyi döndürür, örneğin burada "3" yazılan kullanıcı gibi görünmesini sağlıyoruz.

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

#+RESULTS:
: 3

Öğrencilerin dışa aktarıldığını gördüklerine bağlı olarak, bunu yaptığınızı görmeyebilirler.


Cevap verdiğiniz için teşekkürler John. Ben kod bloğunda giriş işlevine birden fazla çağrı genişletmek mümkün olup olmadığını merak ediyordum (örneğin a = input ("a değeri") b = input ("b değeri")). "# + BEGIN_SRC python" deyiminde genellikle kullandığım ve ": her ikisini de dışa aktar" ders kitabını oluşturmak için, bu satır dışa aktarılan metinde görünmemelidir.
Lgen

Bir oturum kullanırsanız şunlar mümkündür: # + BEGIN_SRC python: session: yok def girdisini dışa aktarır (x): if x == 'a' nın değeri: return 3 elif x == 'b'nin değeri': return 4 # + END_SRC # + SONUÇLAR: # + BEGIN_SRC python: sonuç çıktısı: oturum a = giriş ('a'nın değeri') b = giriş ('b'nin değeri') baskı (a + b) # + END_SRC # + SONUÇLAR::: >>> >>> 7
John Kitchin

2

John Kitchin'in çözümünün bir tamamlayıcısı olarak, input(...)işlevleri "besleyecek" ve bir strnesneyi sistematik olarak döndürecek ardışık değerler sağlamak için bir jeneratör kullanmayı öneriyorum .

#+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 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.