Org Mode Babel - Avaliação interativa de blocos de código em Python

12

Similarmente a esta pergunta, eu gostaria de avaliar (no modo organizacional) blocos de código-fonte Python contendo instruções "input", mas não consigo encontrar uma maneira de fazer uma avaliação interativa (com entrada do usuário) durante a avaliação ou fornecer alguma entrada conhecida antecipadamente (armazenado em um arquivo, por exemplo).

Minha restrição é usar explicitamente as inputinstruções, pois tudo isso deve ser incluído em um livro didático para os alunos.

Exemplo de código:

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

É possível ter uma avaliação interativa ou simulá-la (fornecendo ao código fonte uma entrada falsa)?

Lgen
fonte
Você usará o modo organizacional exportpara gerar seu código de exemplo para os alunos em algum outro formato, por exemplo, html?
Melioratus
A função input () do Python usa apenas texto entre aspas em uma única linha, por exemplo, "hello" ou "hi \ nhello \ nhowdy", correto?
Melioratus
@ Melioratus Thaks por seus comentários; sim, eu uso a exportação no modo organizacional (para LaTeX / pdf) e exporto o código e o resultado. Você também pode usar texto de múltiplas linhas ("" "..." "") como parâmetro para a função de entrada. Meu problema é introduzir valores na função "input" durante a execução do código.
Lgen 6/09/16
Obrigado pelo esclarecimento! Vou postar uma resposta que usa os recursos de programação alfabética, ou seja noweb, do modo organizacional que permitirá testar e exportar seu código com resultados.
Melioratus 06/09
Obrigado, essa poderia ser uma alternativa à solução proposta por John Kitchin (pode estar evitando a etapa de emaranhar?).
Lgen 6/09/16

Respostas:

8

Aqui está uma abordagem alternativa que usa um arquivo emaranhado não exportado para substituir a função de entrada.

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

Dica: pressione C-cC-vtou use o M-xorg-babel-tanglecomando para criar, por exemplo, emaranhar , o example1.pyarquivo.


#+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: O example1.pyarquivo criado a partir do SRCbloco python anterior será importado para o bloco atual usando o cabeçalho builtin : preâmbulo e o valor from example1 import *.

John Kitchin
fonte
Solução muito interessante, obrigado. Aceito como solução e também proponho uma variante baseada no gerador python e retornando sistematicamente um objeto "str" ​​para imitar a função de entrada (...).
Lgen 6/09/16
8

Avalie pythonblocos de código usando programação alfabética no modo organizacional.

Use o :varcabeçalho para atribuir variáveis ​​e teste seu código.

Nota: Se desejar, use elisp (read-string "Prompt: ")e (read-number "Prompt: ")para solicitar a entrada do usuário dentro do emacs.


Exemplo 1 - impressão (a)

  • Atribuir 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
    

Exemplo 2 - print(a + b)

  • Atribuir 1a a.

  • Atribuir 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
    

Exemplo 3 - print(a,b,c)

  • Quando solicitado, Value of adigiteThanks
  • Quando solicitado, Value of bdigite 4.
  • Quando solicitado, Value of cdigite 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 você exporta seu arquivo organizacional, a saída deve ser semelhante ao exemplo abaixo


Exemplo 1 - print(a)

  • Atribuir hello worlda a.

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

Exemplo 2 - print(a + b)

  • Atribuir 1a a.
  • Atribuir 2a b.

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

Exemplo 3 - print(a,b,c)

  • Quando solicitado, Value of adigiteThanks
  • Quando solicitado, Value of bdigite 4.
  • Quando solicitado, Value of cdigite 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
    


Este código foi testado com o
GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK + versão 3.14.13)
Versão em modo de organização: 8.3.2
e github.

Melioratus
fonte
Solução muito interessante; demorou um tempo para eu entender (não estou acostumado a alfabetizar programação) que as instruções no segundo bloco de código-fonte python (por exemplo, a = input ('Value of a')) eram apenas texto de documentação e não eram tratadas como instruções.
Lgen 7/09/16
@Lgen - Obrigado! A programação alfabetizada noweb,, nos recursos do modo organizacional, é incrível e incrivelmente útil! Entre em contato se você quiser exemplos de código adicionais. Se você precisar de algo que não se encaixa bem no formato de perguntas e respostas, fico feliz em publicar no meu repositório GitHub.
Melioratus 7/09/16
6

Eu não acho que é possível obter uma entrada Python verdadeiramente interativa com org-babel.

Você pode usar um preâmbulo para redefinir a função de entrada, para que ela retorne o que você deseja simular o uso da entrada, por exemplo, aqui fazemos parecer que o usuário digitou "3".

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

#+RESULTS:
: 3

Dependendo do que os alunos veem que é exportado, eles podem não perceber que você fez isso.

John Kitchin
fonte
Obrigado John pela proposta de resposta. Eu queria saber se é possível estendê-lo para uma chamada múltipla para a função de entrada no bloco de código (por exemplo, a = entrada ("Valor de a") b = entrada ("Valor de b")). Para construir o texbook, geralmente uso e ": export ambos" na instrução "# + BEGIN_SRC python" para que esta linha não fique visível no texto exportado.
Lgen 6/09/16
Se você usar uma sessão, é possível: # + BEGIN_SRC python: session: exporta nenhuma definição def (x): se x == 'Valor de a': retornar 3 elif x == 'Valor de b': retornar 4 # + END_SRC # + RESULTADOS: # + BEGIN_SRC python: saída dos resultados: sessão a = entrada ('Valor de a') b = entrada ('Valor de b') print (a + b) # + END_SRC # + RESULTADOS::: >>> >>> 7
John Kitchin
2

Como complemento da solução de John Kitchin, proponho usar um gerador para fornecer os valores sucessivos que "alimentarão" as input(...)funções e retornarão um strobjeto sistematicamente.

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