Learning uasyncio and futures
Re: Learning uasyncio and futures
Ah - many thanks pythoncoder - that would explain it. I wasn't aware of that subtlety of python closures, I'm more used to Javascript.
I don't know why it worked at all without the nonlocal keyword - I was running on a linux 1.9.4 build.
I don't know why it worked at all without the nonlocal keyword - I was running on a linux 1.9.4 build.
Re: Learning uasyncio and futures
Code: Select all
Cool, can be done on both sides:pythoncoder wrote: ↑Sat Nov 17, 2018 7:03 amNote thatcould be writtenCode: Select all
results = [None for i in range(count)]
Code: Select all
results = [None] * count
Code: Select all
>>> [None]*2
[None, None]
>>> 3*[None]
[None, None, None]
>>>
Code: Select all
>>> ([None]*2)*([None]*3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported types for __mul__: 'list', 'list'
>>> [[None]*2]*3
[[None, None], [None, None], [None, None]]
>>>
Code: Select all
>>> a=[[None]*2]*3
>>> a
[[None, None], [None, None], [None, None]]
>>> a[1][0]=7
>>> a
[[7, None], [7, None], [7, None]]
>>>
Code: Select all
>>> a=[[1,2],[3,4],[5,6]]
>>> a
[[1, 2], [3, 4], [5, 6]]
>>> a[1]
[3, 4]
>>> a[1][0]=7
>>> a
[[1, 2], [7, 4], [5, 6]]
>>>
Pico-W Access Point static file webserver:
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Learning uasyncio and futures
This is because Python copies lists by reference. So your list of lists is actually a list of list, IYSWIM. To reduce your example to its simplest:
The "pass by reference" method is efficient but this is one of a number of well known cases where the outcome causes puzzlement to those unfamiliar with the quirks of the language.
Code: Select all
>>> z = [1,]
>>> q=[z]*5
>>> q
[[1], [1], [1], [1], [1]]
>>> q[0][0]=999
>>> q
[[999], [999], [999], [999], [999]]
>>>
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Learning uasyncio and futures
Thanks for the explanation.
This allows for an evil thimblerig game
This allows for an evil thimblerig game
Code: Select all
>>> thimbles=[['pea',]]*3
>>> thimbles
[['pea'], ['pea'], ['pea']]
>>> thimbles[0][0]=None
>>> thimbles[2][0]=None
>>> thimbles[0][0],thimbles[1][0]=thimbles[1][0],thimbles[0][0]
>>> thimbles[0][0],thimbles[2][0]=thimbles[2][0],thimbles[0][0]
>>>
>>> thimbles[2][0]
>>>
Pico-W Access Point static file webserver:
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
Re: Learning uasyncio and futures
Back to topic, and sorry, was my fault.
Compiling uasyncio modules was not possible on ESP8266.
I just replaced the two "uasyncio/*.py" files with *.mpy files.
Now poorfutures.py just runs, even without calling gc.collect() free memory after powering ESP_01s module of 26096 bytes only reduces to 9456, and poorfutures.py (and uasyncio) works perfectly on ESP8266:
Code: Select all
$ webrepl_client.py -p abcd 192.168.4.1
Password:
WebREPL connected
>>>
>>>
MicroPython v1.9.4-272-g46091b8a on 2018-07-18; ESP module with ESP8266
Type "help()" for more information.
>>> uos.listdir('uasyncio')
['core.mpy', '__init__.mpy']
>>> gc.mem_free()
26096
>>> import poorfutures
0 of 3
0 of 5
0 of 1
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
[False, False, False]
1 of 3
1 of 5
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
2 of 3
2 of 5
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
[False, False, True]
3 of 5
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
4 of 5
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, False, True]
[True, True, True]
results: ['banana', 'satsuma', 'mango']
>>> gc.mem_free()
9456
>>>
Pico-W Access Point static file webserver:
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
https://github.com/Hermann-SW/pico-w
Tiny MicroPython robots (the PCB IS the robot platform)
viewtopic.php?f=5&t=11454
webrepl_client.py
https://github.com/Hermann-SW/webrepl#webrepl-shell
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Learning uasyncio and futures
I use frozen bytecode for uasyncio on ESP8266. This avoids having to cross compile applications (unless they are large).
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Learning uasyncio and futures
I've been doing a bit of reading around futures to learn a bit more and found a couple of interesting references:
Firstly, Javascript has the Promises/A+ specification - https://promisesaplus.com - which has been widely adopted and is largely seen as a step-up from the previous "callback hell". I quite like promises and find them fairly intuitive to work with, but they appear to have a number of shortcomings:
So - a couple of the deficiencies of Promises that Flutures tries to address:
Firstly, Javascript has the Promises/A+ specification - https://promisesaplus.com - which has been widely adopted and is largely seen as a step-up from the previous "callback hell". I quite like promises and find them fairly intuitive to work with, but they appear to have a number of shortcomings:
- difficult/complex to implement correctly
- difficult to cancel operations
So - a couple of the deficiencies of Promises that Flutures tries to address:
- simpler to implement/reason about - whereas Promises allow arbitrary listeners to subscribe to the result of a Promise, Flutures explicitly plumb in a single "reject" continuation/callback (for error handling) and single "resolve" continuation/callback (for proceeding). This makes the implementation simpler, because they essentially "unicast" their result, but a bit more work is required to "broadcast" results to multiple subsequent Flutures.
- designed to support cancellation - when you "fork" a Fluture (ie. kick off its computation) it can (optionally) return a callback to cancel that specific Fluture. When called, that cancel callback should, in turn, propagate the cancel message to any Flutures it is depending on.
Re: Learning uasyncio and futures
A couple of words, how I, the author of uasyncio learned it. Well, I of course started with "big" Python version, asyncio. Then I just reimplemente a subset of each which made sense for very small-memory systems, leaving out everything which could be left out (out of the core, with the idea that other things can be implemented on top of it as needed).
I personally can't see any other way to start, except by following Python in general - the whole MicroPython project was originally intended for people who know Python and would like to use it in more constrained environments (disclaimer: intended by me, as a second largest contributor to the MicroPython, other parties may had other intentions). MicroPython docs, while fairly detailed in comparison with similar projects, still usually describe the differences to "big" Python, etc.
It turns out that MicroPython has a unique challenge that a lot of people coming to it who aren't familiar (enough or at all) with Python. My personal position in that regard is firm - learn Python, if you're interested in MicroPython, it's fully worth it. But then, I'm very happy that the forum has enough people who patiently explain things to novices, which are well described in the Python docs .
I personally can't see any other way to start, except by following Python in general - the whole MicroPython project was originally intended for people who know Python and would like to use it in more constrained environments (disclaimer: intended by me, as a second largest contributor to the MicroPython, other parties may had other intentions). MicroPython docs, while fairly detailed in comparison with similar projects, still usually describe the differences to "big" Python, etc.
It turns out that MicroPython has a unique challenge that a lot of people coming to it who aren't familiar (enough or at all) with Python. My personal position in that regard is firm - learn Python, if you're interested in MicroPython, it's fully worth it. But then, I'm very happy that the forum has enough people who patiently explain things to novices, which are well described in the Python docs .
That's the right way to do it - read about this stuff. Reading is exciting! Read docs, read code, read everything.But it has been interesting reading about this stuff
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
uasyncio performance and API
@apois uasyncio is highly efficient. Scheduling is performed without RAM allocation: this ensures that context switches are always fast (156μs on the Pyboard) as they never trigger garbage collection. Non-allocation also avoids contributing to heap fragmentation. It is possible to run 1000 coroutines on a Pyboard.
The uasyncio API is heavily based on the standard Python asyncio library so it is easy to write asynchronous code which is portable between CPython and MicroPython. I regard it as a major achievement by @pfalcon.
An alternative library using a different paradigm could be written, and it might be a thoroughly worthwhile exercise. But achieving comparable performance in a microcontroller context might prove challenging.
The uasyncio API is heavily based on the standard Python asyncio library so it is easy to write asynchronous code which is portable between CPython and MicroPython. I regard it as a major achievement by @pfalcon.
An alternative library using a different paradigm could be written, and it might be a thoroughly worthwhile exercise. But achieving comparable performance in a microcontroller context might prove challenging.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Learning uasyncio and futures
@pfalcon - thanks for your advice. Yes - I agree - compatibility with (a subset of) Python 3 is a crucial goal. That's kind of how I ended up down the rabbit-hole of this thread - I wanted to do what I thought would be a simple asyncio.gather() but realised that this functionality wasn't available in uasyncio, so started look for options to achieve it. But I'm certainly not qualified to try reimplementing a production-ready async library in micropython! Just curious about options for achieving my use case, which I initially thought would be straightforward.
Regarding your comment about python novices - don't discount the fact that there is another group - developers like myself who are familiar with python but have never had reason to use asyncio until trying micropython, where it becomes much more compelling than on the desktop/server. My async experience is all node or client-side javascript - hence my attempts to understand uasyncio in terms of those.
@pythoncoder - yes - an efficient implementation is key, as this enables close to system-level functionality. For my particular use case though, it is more about higher-level programming convenience - I'm not worried about wasting a few hundred milliseconds if my sensor reading takes 5 seconds, and on an ESP32 I have room to be a bit "flabby" on memory usage . But yes - the underlying uasyncio is an amazing achievement for device-level programming.
Regarding your comment about python novices - don't discount the fact that there is another group - developers like myself who are familiar with python but have never had reason to use asyncio until trying micropython, where it becomes much more compelling than on the desktop/server. My async experience is all node or client-side javascript - hence my attempts to understand uasyncio in terms of those.
@pythoncoder - yes - an efficient implementation is key, as this enables close to system-level functionality. For my particular use case though, it is more about higher-level programming convenience - I'm not worried about wasting a few hundred milliseconds if my sensor reading takes 5 seconds, and on an ESP32 I have room to be a bit "flabby" on memory usage . But yes - the underlying uasyncio is an amazing achievement for device-level programming.