Org Mode Babel - การประเมินการบล็อกรหัสแบบโต้ตอบใน Python


12

ในทำนองเดียวกันกับคำถามนี้ฉันต้องการประเมิน (ในโหมด org) บล็อกซอร์สของ Python ที่มีคำแนะนำ "อินพุต" แต่ฉันไม่สามารถหาวิธีที่จะมีการประเมินผลแบบโต้ตอบ (กับอินพุตของผู้ใช้) ในระหว่างการประเมินผล ล่วงหน้า (เก็บไว้ในไฟล์เช่น)

ข้อ จำกัด ของฉันคือการใช้inputคำแนะนำอย่างชัดเจนเนื่องจากทั้งหมดนี้ควรรวมอยู่ในตำราเรียนสำหรับนักเรียน

ตัวอย่างของรหัส:

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

เป็นไปได้หรือไม่ที่จะมีการประเมินแบบโต้ตอบหรือจำลองมัน (โดยการป้อนรหัสปลอมให้กับซอร์สโค้ด)


คุณจะใช้โหมดองค์กรexportเพื่อสร้างโค้ดตัวอย่างสำหรับนักเรียนในรูปแบบอื่นเช่น html หรือไม่
Melioratus

ฟังก์ชันอินพุต Python ()ใช้ข้อความที่ยกมาในบรรทัดเดียวเช่น "hello" หรือ "hi \ nhello \ nhowdy" ถูกต้องหรือไม่
Melioratus

@Melioratus Thaks สำหรับความคิดเห็นของคุณ; ใช่ฉันใช้การส่งออกโหมด org (ไปยัง LaTeX / pdf) และฉันส่งออกทั้งรหัสและผลลัพธ์ คุณยังสามารถใช้ข้อความหลายบรรทัด ("" "... " "") เป็นพารามิเตอร์สำหรับฟังก์ชั่นอินพุต ปัญหาของฉันคือการแนะนำค่าให้กับฟังก์ชั่น "อินพุต" ในระหว่างการประมวลผลโค้ด
Lgen

ขอขอบคุณสำหรับการชี้แจง! ฉันจะโพสต์คำตอบที่ใช้คุณสมบัติการเขียนโปรแกรมความรู้เช่นnowebของโหมด org ที่จะช่วยให้คุณสามารถทดสอบและส่งออกรหัสของคุณด้วยผลลัพธ์
Melioratus

ขอบคุณนี่อาจเป็นทางเลือกใหม่สำหรับวิธีแก้ปัญหาที่เสนอโดย John Kitchin (อาจหลีกเลี่ยงขั้นตอนการพันกันได้?)
Lgen

คำตอบ:


8

นี่เป็นวิธีทางเลือกที่ใช้ไฟล์ tangled ที่ไม่ถูกเอ็กซ์พอร์ตเพื่อแทนที่ฟังก์ชันอินพุต

#+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บล็อกจะถูกนำเข้ามาในบล็อกปัจจุบันใช้ builtin : คำนำfrom example1 import *ส่วนหัวและความคุ้มค่า


ทางออกที่น่าสนใจมากขอบคุณ ฉันยอมรับว่าเป็นวิธีแก้ปัญหาและฉันจะเสนอชุดตัวเลือกตามตัวสร้างของหลามและส่งคืนวัตถุ "str" ​​อย่างเป็นระบบเพื่อเลียนแบบฟังก์ชันอินพุต (... )
Lgen

8

ประเมินpythonบล็อคโค้ดโดยใช้การเขียนโปรแกรมแบบรู้เท่าทันในโหมดองค์กร

ใช้:varส่วนหัวเพื่อกำหนดตัวแปรและทดสอบรหัสของคุณ

หมายเหตุ: หากต้องการใช้elisp (read-string "Prompt: ")และ(read-number "Prompt: ")แจ้งให้ผู้ใช้ป้อนข้อมูลภายใน emacs


ตัวอย่างที่ 1 - พิมพ์ (ก)

  • กําหนดการ hello worlda


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

  • กําหนดการ 1a

  • กําหนดการ 2b


    #+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 b4
  • เมื่อได้รับแจ้งสำหรับใส่Value of cyour 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 worlda

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

ตัวอย่างที่ 2 - print(a + b)

  • กําหนดการ1a
  • กําหนดการ2b

    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 b4
  • เมื่อได้รับแจ้งสำหรับใส่Value of cyour 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 + เวอร์ชัน 3.14.13)
Org-Mode เวอร์ชั่น: 8.3.2
และ github


ทางออกที่น่าสนใจมาก มันใช้เวลาสำหรับฉันที่จะเข้าใจ (ฉันไม่คุ้นเคยกับการเขียนโปรแกรมความรู้) ว่าคำแนะนำในแหล่งไพ ธ อนที่สอง (เช่น a = input ('Value of a')) เป็นเพียงข้อความเอกสารและไม่ได้รับการปฏิบัติตามคำแนะนำ
Lgen

@Lgen - ขอบคุณ! การเขียนโปรแกรมความรู้nowebในคุณสมบัติโหมด org นั้นน่าทึ่งและมีประโยชน์อย่างเหลือเชื่อ! โปรดแจ้งให้เราทราบหากคุณต้องการตัวอย่างโค้ดเพิ่มเติม หากคุณต้องการบางสิ่งที่ไม่ตรงกับรูปแบบของคำถาม & คำตอบฉันยินดีที่จะโพสต์ไปยังที่เก็บ GitHub ของฉัน
Melioratus

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

พวกเขาอาจไม่เห็นว่าคุณได้ทำสิ่งนี้ขึ้นอยู่กับสิ่งที่นักเรียนเห็นว่าถูกส่งออก


ขอบคุณ John สำหรับคำตอบที่คุณเสนอ ฉันสงสัยว่ามันเป็นไปได้ที่จะขยายไปยังการเรียกหลายฟังก์ชั่นอินพุตในบล็อคโค้ด (เช่น a = input ("Value of a") b = input ("Value of b")) เพื่อสร้าง texbook โดยทั่วไปฉันใช้และ ": ส่งออกทั้งสอง" ในคำสั่ง "# + BEGIN_SRC python" ดังนั้นบรรทัดนี้ไม่ควรมองเห็นได้ในข้อความที่ส่งออก
Lgen

หากคุณใช้เซสชันเป็นไปได้: # + BEGIN_SRC python: session: ไม่มีการป้อนข้อมูล def (x): ถ้า x == 'ค่า a': return 3 elif x == 'ค่า b': return 4 # + END_SRC # + RESULTS: # + BEGIN_SRC python: ผลลัพธ์ผลลัพธ์: เซสชั่น a = อินพุต ('Value of a') b = อินพุต ('Value of b') พิมพ์ (a + b) # + END_SRC # + RESULTS:: >>> >>> 7
John Kitchin

2

ในฐานะที่เป็นส่วนเสริมของโซลูชันของ John Kitchin ฉันเสนอให้ใช้ตัวกำเนิดเพื่อให้ค่าต่อเนื่องที่จะ "ป้อน" 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 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.