Org Mode Babel - Interaktywna ocena bloku kodu w Pythonie

12

Podobnie jak w przypadku tego pytania , chciałbym ocenić (w trybie org) bloki kodu źródłowego Pythona zawierające instrukcje „wejściowe”, ale nie mogę znaleźć sposobu na interaktywną ocenę (z wejściem użytkownika) podczas oceny lub dać jej znać z góry (na przykład przechowywane w pliku).

Moim ograniczeniem jest jawne stosowanie inputinstrukcji, ponieważ wszystko to powinno być zawarte w podręczniku dla studentów.

Przykład kodu:

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

Czy możliwe jest przeprowadzenie takiej interaktywnej oceny lub jej symulacja (poprzez podanie kodu źródłowego fałszywych danych wejściowych)?

Lgen
źródło
Czy będziesz używać trybu organizacji exportdo generowania przykładowego kodu dla uczniów w innym formacie, np. HTML?
Melioratus
Funkcja input () Pythona pobiera cytowany tekst tylko w jednym wierszu, np. „Cześć” lub „cześć \ nhello \ nhowdy”, prawda?
Melioratus
@Melioratus Thaks za komentarze; tak, korzystam z eksportu w trybie org (do LaTeX / pdf) i eksportuję zarówno kod, jak i wynik. Można również użyć tekstu wielowierszowego („” „...” ”)) jako parametru funkcji wejściowej. Moim problemem jest wprowadzenie wartości do funkcji „wejściowej” podczas wykonywania kodu.
Lgen,
Dziękuję za wyjaśnienie! Wyślę odpowiedź, która używa umiejętności programowania, tj. nowebTrybu org, który pozwoli ci przetestować i wyeksportować kod z wynikami.
Melioratus
Dzięki, może to być alternatywa dla rozwiązania zaproponowanego przez Johna Kitchina (być może unikasz plątania się?).
Lgen,

Odpowiedzi:

8

Oto alternatywne podejście, w którym nieeksportowany plik splątany zastępuje funkcję wprowadzania.

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

Wskazówka: Naciśnij przycisk C-cC-vtlub użyj M-xorg-babel-tanglepolecenia do tworzenia, czyli splot , ten example1.pyplik.


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

Uwaga:example1.py plik, który został stworzony z poprzedniego Pythona SRCbloku zostaną zaimportowane do bieżącego bloku stosując polecenie wbudowane : preambuły nagłówka i wartości from example1 import *.

John Kitchin
źródło
Bardzo interesujące rozwiązanie, dzięki. Akceptuję to jako rozwiązanie i zaproponuję również wariant oparty na generatorze Pythona i systematycznie zwracający obiekt „str”, który naśladuje funkcję wejściową (...).
Lgen,
8

Oceniaj pythonbloki kodu, używając umiejętności czytania i pisania w trybie org.

Użyj :varnagłówka, aby przypisać zmienne i przetestować kod.

Uwaga: W razie potrzeby użyj elisp (read-string "Prompt: ")i, (read-number "Prompt: ")aby poprosić użytkownika o wprowadzenie danych w emacsie.


Przykład 1 - wydrukuj (a)

  • Przypisz hello worlddo 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
    

Przykład 2 - print(a + b)

  • Przypisz 1do a.

  • Przypisz 2do 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
    

Przykład 3 - print(a,b,c)

  • Po wyświetleniu monitu o Value of awprowadzenieThanks
  • Po wyświetleniu monitu o Value of bwprowadzenie 4.
  • Po wyświetleniu monitu o Value of cwprowadzenie 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
    

Po wyeksportowaniu pliku org wynik powinien wyglądać podobnie do poniższego przykładu


Przykład 1 - print(a)

  • Przypisz hello worlddo a.

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

Przykład 2 - print(a + b)

  • Przypisz 1do a.
  • Przypisz 2do b.

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

Przykład 3 - print(a,b,c)

  • Po wyświetleniu monitu o Value of awprowadzenieThanks
  • Po wyświetleniu monitu o Value of bwprowadzenie 4.
  • Po wyświetleniu monitu o Value of cwprowadzenie 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
    


Ten kod został przetestowany z
GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK + wersja 3.14.13)
Wersja trybu org: 8.3.2
i github.

Melioratus
źródło
Bardzo interesujące rozwiązanie; zajęło mi zrozumienie (nie jestem przyzwyczajony do programowania), że instrukcje w drugim bloku źródłowym Pythona (np. a = input („Wartość a”)) były tylko tekstem dokumentacji i nie były traktowane jako instrukcje.
Lgen,
@Lgen - Dzięki! Umiejętne programowanie nowebw trybie org jest niesamowite i niezwykle przydatne! Daj mi znać, jeśli chcesz dodatkowe przykłady kodu. Jeśli potrzebujesz czegoś, co nie pasuje dobrze do formatu pytań i odpowiedzi, chętnie opublikuję w moim repozytorium GitHub.
Melioratus
6

Nie sądzę, że można uzyskać prawdziwie interaktywne wejście w Pythonie za pomocą org-babel.

Możesz użyć preambuły, aby ponownie zdefiniować funkcję wprowadzania, aby zwracała to, co chcesz symulować użycie danych wejściowych, np. Tutaj wyglądamy, jakby użytkownik wpisał „3”.

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

#+RESULTS:
: 3

W zależności od tego, co uczniowie widzą, że jest eksportowane, mogą nie zobaczyć, że to zrobiłeś.

John Kitchin
źródło
Dzięki, John, za propozycję odpowiedzi. Zastanawiałem się, czy można rozszerzyć to na wielokrotne wywołanie funkcji wejściowej w bloku kodu (np. A = input („Wartość a”) b = input („Wartość b”)). Aby zbudować texbook, zwykle używam i „: export oba” w instrukcji „# + BEGIN_SRC python”, więc ta linia nie powinna być widoczna w eksportowanym tekście.
Lgen,
Jeśli używasz sesji, możliwe jest: # + BEGIN_SRC python: session: export none def input (x): if x == 'Wartość a: return 3 elif x ==' Wartość b ': return 4 # + END_SRC # + WYNIKI: # + BEGIN_SRC python: wyniki wyniki: sesja a = dane wejściowe („Wartość a”) b = dane wejściowe („Wartość b”) drukuj (a + b) # + END_SRC # + WYNIKI::: >>> >>> 7
John Kitchin
2

Jako uzupełnienie rozwiązania Johna Kitchina proponuję użyć generatora, aby zapewnić kolejne wartości, które „zasilą” input(...)funkcje i będą strsystematycznie zwracać obiekt.

#+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
źródło