How to import int variable out of raw_repl

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Shafagh777
Posts: 6
Joined: Fri Feb 19, 2021 5:02 pm

How to import int variable out of raw_repl

Post by Shafagh777 » Thu Mar 04, 2021 10:21 am

Hello friends

I have written the following codes in Python prompt to call variable (x) from raw_repl to perform a simple mathematical operation like y=x*2 as follow:

import pyboard
pyb = pyboard. Pyboard ('COM3')
pyb.enter_raw_repl()
pyb.exec('import pyb')
pyb.exec('x=2')
pyb.exec('y=x*2)
pyb.exit raaw repl()

.... and this works. Now, my question is how i can call the variable x out of raw_repl. For instance the following script gives me an error:

import pyboard
pyb = pyboard. Pyboard ('COM3')
pyb.enter_raw_repl()
pyb.exec('import pyb')
x=2
pyb.exec('y=x*2)
pyb.exit raaw repl()

Traceback (most recent call last):
... line 451, in exec_
raise PyboardError("exception", ret, ret_err)
pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n File "<stdin>", line 1, in <module>\r\nNameError: name \'x\' isn\'t defined\r\n')

I would be appreciated if anyone can give me some hints on how to call int 'x' variable out of pyb.exec('...') and execute ('y=x*2')

Thanks

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How to import int variable out of raw_repl

Post by dhylands » Thu Mar 04, 2021 6:00 pm

Try this instead:

Code: Select all

#!/usr/bin/env python3

import pyboard
pyb = pyboard.Pyboard('/dev/cu.usbmodem3389337E34332')
pyb.enter_raw_repl()
pyb.exec('import pyb')
pyb.exec('x=2')
pyb.exec('y=x*2')
output = pyb.exec('print(y)')
pyb.exit_raw_repl()
y = eval(output)
print('y =', y)
If you're planning on sending lots of code, then you might want to use the inspect module. Something like this:

Code: Select all

#!/usr/bin/env python3

import inspect

def foo():
  x = 2
  y = x * 2
  return y

import pyboard
pyb = pyboard.Pyboard('/dev/cu.usbmodem3389337E34332')

source = inspect.getsource(foo)
pyb.enter_raw_repl()
output = pyb.exec(source + 'print(foo())\n')
pyb.exit_raw_repl()
y = eval(output)
print('y =', y)

Shafagh777
Posts: 6
Joined: Fri Feb 19, 2021 5:02 pm

Re: How to import int variable out of raw_repl

Post by Shafagh777 » Fri Mar 05, 2021 3:46 pm

Thank you so much dhylands for the reply. I have tried the code and it works but, while introducing the variable x in function ( like foo(x)), it gives me an error that x isn't defined.

import inspect

def foo(x):
y = x * 2
return y

import pyboard
pyb = pyboard.Pyboard('COM3')
source = inspect.getsource(foo)
pyb.enter_raw_repl()
output = pyb.exec(source + 'print(foo())\n')
pyb.exit_raw_repl()
y = eval(output)
print('y =', y)



I have also tried this and received the same error:

import inspect

def foo(x):
y = x * 2
return y

import pyboard
pyb = pyboard.Pyboard('COM3')
source = inspect.getsource(foo)
pyb.enter_raw_repl()
output = pyb.exec(source + 'print(foo(x))\n')
pyb.exit_raw_repl()
y = eval(output)
print('y =', y)

I appreciate you giving me a hint to cope with this challenge.

regards

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How to import int variable out of raw_repl

Post by dhylands » Fri Mar 05, 2021 5:56 pm

Sure - if you look at the source you're sending, it looks like this:

Code: Select all

def foo(x):
    y = x * 2
    return y
foo(x)
which of course fails because there is no x defined. You could change foo(x) to foo(4) or change it to assign a value to x before calling foo.

You could make youre code a little more exotic and do something like this:

Code: Select all

#!/usr/bin/env python3

import inspect

def foo(x):
  y = x * 2
  return y

import pyboard
pyb = pyboard.Pyboard('/dev/cu.usbmodem3389337E34332')

def remote(func, *args, **kwargs):
    func_name = func.__name__
    func_src = inspect.getsource(func)
    args_arr = [repr(i) for i in args]
    kwargs_arr = ["{}={}".format(k, repr(v)) for k, v in kwargs.items()]
    func_src += 'output = ' + func_name + '('
    func_src += ', '.join(args_arr + kwargs_arr)
    func_src += ')\n'
    func_src += 'print(output)\n'
    pyb.enter_raw_repl()
    output = pyb.exec(func_src)
    pyb.exit_raw_repl()
    return eval(output)


y = remote(foo, 4)
print('y =', y)
This is essentially what rshell does: https://github.com/dhylands/rshell/blob ... 1570-L1626

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How to import int variable out of raw_repl

Post by dhylands » Fri Mar 05, 2021 8:17 pm

Here's a version that creates a @remote decorator and makes calling the functions a bit more natural:

Code: Select all

#!/usr/bin/env python3

import inspect
import pyboard

pyb = pyboard.Pyboard('/dev/cu.usbmodem3389337E34332')

def remote(func):
    def wrapper(*args, **kwargs):
        return do_remote(func, *args, **kwargs)
    return wrapper

def do_remote(func, *args, **kwargs):
    func_name = func.__name__
    func_src = inspect.getsource(func).replace('@remote\n', '')
    args_arr = [repr(i) for i in args]
    kwargs_arr = ["{}={}".format(k, repr(v)) for k, v in kwargs.items()]
    func_src += 'print(repr(' + func_name + '(' + ', '.join(args_arr + kwargs_arr) + ')))\n'
    pyb.enter_raw_repl()
    output = pyb.exec(func_src)
    pyb.exit_raw_repl()
    return eval(output)

@remote
def foo(x):
  return x * 2

@remote
def sysname():
  import os
  return os.uname().sysname

print('sysname =', sysname())
print('foo(4) =', foo(4))
along with a call to print os.uname().sysname just to prove it's really running on the pyboard.

Result of running the above (I called my script pyboard_eval.py):

Code: Select all

$ ./pyboard_eval.py 
sysname = pyboard
foo(4) = 8

Shafagh777
Posts: 6
Joined: Fri Feb 19, 2021 5:02 pm

Re: How to import int variable out of raw_repl

Post by Shafagh777 » Mon Mar 08, 2021 1:30 pm

dear dhylands, I don't know how to appreciate your wonderful and quick response to my question. it worked perfectly.

Post Reply