Functions in Micro-python - esp8266

i have a question about micro-python that how to make and call functions in micro-python or any other idea related to functions
my code throwing an error that NameError: name 'my_func' isn't defined
import time
from machine import Pin
led = Pin(2, Pin.OUT)
btn = Pin(4, Pin.IN, Pin.PULL_UP)
while True:
if not btn.value():
my_func()
while not btn():
pass
def my_func():
led(not led())
time.sleep_ms(300)

Generaly, what I do following: Imports then Functions and after that- rest of the flow
Slightly modified your code to pass LED object for function
import time
from machine import Pin
def my_func(myLed):
myLed.value(not myLed.value()) # invert boolean value
time.sleep_ms(300)
led = Pin(2, Pin.OUT)
btn = Pin(4, Pin.IN, Pin.PULL_UP)
while True:
if not btn.value():
my_func(led)
while not btn():
pass

you need to import a function before it can be called.

Related

How to pass values from one subscriber's callback function to another in rosnode

My question is how to pass a value from one subscriber's callback function to another.
does this make sense ?
import rospy
from sensor_msgs.msg import LaserScan, Int32
from xxx2.msg import xxyy2
global x
x = None
def callback2(data):
x=data[0]
def callback(data):
if x > data.ranges[0]:
print("nice")
rospy.Subscriber("/scan", LaserScan, callback)
rospy.Subscriber("topic", xxyy2, callback2)
rospy.spin()
You can "pass" variable x to both callbacks as you can pass it to any other function, by making x global the way you did or by making x and the callback functions members of a class which allows you to just access them.
Callbacks are by default called sequentially so you don't need to worry about race conditions in this case.
Depending on your use case you can synchronize the callbacks with message filters if needed.
I would change the code a bit, I think the way you have wrote it, the global variable is not properly setup.
The different is that instead of using the instruction global at the variable definition, you have to use it inside the callbacks.
import rospy
from sensor_msgs.msg import LaserScan, Int32
from xxx2.msg import xxyy2
x = None
def callback2(data):
global x
x = data[0]
def callback(data):
global x
if x > data.ranges[0]:
print("nice")
rospy.Subscriber("/scan", LaserScan, callback)
rospy.Subscriber("topic", xxyy2, callback2)
rospy.spin()
Regards

My code using user_data_dir does not work and it gives an error saying 'self' is not defined. Can someone explain to me why?

The following is a snippet of my code. When I tried running this, the error states that 'self' is not defined. I copied this code online because I don't really know how to use the function user_data_dir. I know that it works (I'm using Windows to write this) with just store = JsonStore('user.json') but I've been reading that using the function user_data_dir would be useful because it is a general function that creates a writeable path for various systems. Would be great if someone could help explain this!
from kivy.storage.jsonstore import JsonStore
from os.path import join
data_dir = getattr(self, 'user_data_dir')
store = JsonStore(join(data_dir,'user.json'))
class Welcome(Screen):
pass
data_dir = getattr(self, 'user_data_dir')
When you copied this line, it was somewhere inside some class's function:
class Some:
def func(self):
data_dir = getattr(self, 'user_data_dir')
Method located inside class in Python receives self as first parameter.
But not every object has user_data_dir attribute: as inclement noticed above it's App objects attribute. You should do something like:
class MyApp(App):
def build(self):
data_dir = getattr(self, 'user_data_dir')
store = JsonStore(join(data_dir,'user.json'))
# ...
Upd:
You can store path to json file inside app class and access to app instance to get this path with App.get_running_app():
class MyApp(App):
#property # see https://www.programiz.com/python-programming/property
def storage(self):
return join(self.user_data_dir, 'user.json')
and later in any place you want:
class SomeClass():
def some_func(self):
print('here\'s our storage:', App.get_running_app().storage)

Combina pyramid with jinja2 install_gettext_translations function?

I have a pyramid application that uses a translation factory defined in this way:
from pyramid.i18n import get_localizer, TranslationStringFactory
from pyramid.threadlocal import get_current_request
def add_renderer_globals(event):
request = event.get('request')
if request is None:
request = get_current_request()
event['_'] = request.translate
event['localizer'] = request.localizer
tsf = TranslationStringFactory('climmob3')
def add_localizer(event):
request = event.request
localizer = get_localizer(request)
def auto_translate(string):
return localizer.translate(tsf(string))
request.localizer = localizer
request.translate = auto_translate
It works fine, however somewhere else I use jinja2 render() function to render small pieces of reusable code (snippets) as a jinja2 extension:
from jinja2 import Environment
jinjaEnv = Environment(extensions=['jinja2.ext.i18n'])
output = template.render(snippetVars=kw,renderer='snippet')
The problem here is that when I use the '_' translation function in the template code I get:
UndefinedError: 'gettext' is undefined
I saw some posts that maybe I need to use jinjaEnv.install_gettext_translations() but I cannot make it work. I tried:
jinjaEnv.install_gettext_translations(pyramid.il8n)
jinjaEnv.install_gettext_translations(tsf)
How can I integrate jinjaEnv.install_gettext_translations() with my pyramid translation factory?
Depending on your exact case, you could use pyramid_jinja2 or get inspiration from it. It creates a GetTextWrapper https://github.com/Pylons/pyramid_jinja2/blob/28944ce627745691ccd1603c56251e038aadd892/pyramid_jinja2/i18n.py that makes its way in the options passed when creating the Environment https://github.com/Pylons/pyramid_jinja2/blob/28944ce627745691ccd1603c56251e038aadd892/pyramid_jinja2/settings.py#L133
https://github.com/Pylons/pyramid_jinja2/blob/28944ce627745691ccd1603c56251e038aadd892/pyramid_jinja2/__init__.py#L394
https://github.com/Pylons/pyramid_jinja2/blob/28944ce627745691ccd1603c56251e038aadd892/pyramid_jinja2/__init__.py#L404-L405
The wrapper is needed because the localizer will change every request, depending on the user locale.
Or you can pass the gettext and ngettext arguments directly when you render. In you case, it would look something like:
localizer = request.localizer
def gt(message):
return localizer.translate(message, domain='your-domain')
def ngt(singular, plural, n):
return localizer.pluralize(singular, plural, n, domain='your-domain')
output = template.render(
snippetVars=kw,
renderer='snippet',
gettext=gt,
ngettext=ngt,
)

_repr_latex_ method not working anymore in Jupyter / IPython notebook

I have an Expr class to represent mathematical expressions in which I defined
def _latex(self):
""":return: string LaTex formula"""
(...)
return res
def _repr_latex_(self):
return r'$%s$'%self._latex() #tried several variations of this...
#property
def latex(self):
from IPython.display import Math
return Math(self._latex())
as you can see on http://nbviewer.ipython.org/github/Goulu/Goulib/blob/master/notebook.ipynb at cell [42], latex is correctly rendered when explicitly specified by the property
but fails next cell when called though _repr_latex_ with a UnicodeDecodeError.
e2(e1)._latex() returns '\sin(3x+2)' with no unicode, so what's wrong here ?
Thanks !
well... it was partly my mistake : my Expr class inherits from my Plot class which has a _repr_svg_ method and Jupyter called this one by default instead of _repr_latex_ ...
Ok But:
the error message in Jupyter/IPython doesn't mention this
I still don't know how to select the default _repr_xxx_ method of a class

Getting value of a Numeric Property in kivy

I am trying to use a NumericProperty but getting Type errors when trying to use it as a value
My code looks like this
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
class Segment(Widget):
def __init__(self, segments):
super(Segment, self).__init__()
self.segments = NumericPropery(segments)
def build(self):
for i in range(0, self.segments):
# Do something
I get an error :
for i in range(0, self.segments):
TypeError: range() integer end argument expected, got kivy.properties.NumericProperty.
so I tried using self.segments.get() instead, but then I got this error
TypeError: get() takes exactly one argument (0 given)
apperently the get function expects <kivy._event.EventDispatcher> object argument
Any idea how to get around this?
I had a similar problem with this code ...
class GameModel(object):
some_number = NumericProperty(1)
def __init__(self):
self.some_number = 2
... which raised the error:
TypeError: Argument 'obj' has incorrect type (expected kivy._event.EventDispatcher, got GameModel)
I did declare the property at class level though. In my case the problem was that the class itself was not derived from a Kivy Widget class or - as stated in the error message - from an EventDispatcher Object
Deriving from EventDispatcher fixed my problem:
class GameModel(EventDispatcher):
Hope this is helpful for someone else some day ;-)
You have to declare properties at class level.
class Segment(Widget):
segments = NumericProperty()
This will give the correct behaviour. The problem is that properties do their own management of per-instance values and interacting with the eventloop etc.. If you don't declare them at class level, they don't get to do this, so your functions only see the NumericProperty itself (which is your problem).

Resources