What sort of exception when a class can't find something?
What sort of exception should a class raise in __init__() when it can't find an appropriate set of data for the parameter passed in to the class instantiation? E.g. I have a database with some names and address in and have a class Person that gets all the details for a person given their name. person.Person('Fred') ... ... If Fred doesn't exist in the database what sort of exception should there be? Is it maybe a ValueError? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: What sort of exception when a class can't find something?
Several helpful replies, thank you all. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Why do I always get an exception raised in this __init__()?
Chris Green wrote: [snip code and question] Sorry folks, it was a caching problem, I wasn't running the code I thought I was running! When I made sure I had cleared everything out and tried again it all worked as I expected. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Why do I always get an exception raised in this __init__()?
I'm obviously doing something very silly here but at the moment I can't see what. Here's the code:- #!/usr/bin/python3 # # # GPIO # import gpiod # # # Simple wrapper class for gpiod to make set and clearing outputs easier # class Gpiopin: def __init__(self, pin): # # # scan through the GPIO chips to find the line/pin we want # for c in ['gpiochip0', 'gpiochip1', 'gpiochip2', 'gpiochip3']: chip = gpiod.Chip(c) for l in range(32): line = chip.get_line(l) if pin in line.name(): print("Found: ", line.name()) return else: raise ValueError("Can't find pin '" + pin + "'") def print_name(self): print (self.line.name()) def set(self): self.line.set_value(1) def clear(self): self.line.set_value(0) This is by no means the final code, the print() in the __init__() is just a diagnostic for example. However I really can't understand why I see the following when I try it:- >>> import ngp >>> ngp.Gpiopin("P9_23") Found: P9_23 Traceback (most recent call last): File "", line 1, in File "/home/chris/.cfg/hosts/bbb/bin/ngp.py", line 24, in __init__ return ValueError: Can't find pin 'P9_23' >>> Does a return in __init__() not do what I think it does? How else could/should I do this? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Why do I always get an exception raised in this __init__()?
Alan Gauld wrote: > On 31/08/2023 22:15, Chris Green via Python-list wrote: > > > class Gpiopin: > > > > def __init__(self, pin): > > # > > # > > # scan through the GPIO chips to find the line/pin we want > > # > > for c in ['gpiochip0', 'gpiochip1', 'gpiochip2', 'gpiochip3']: > > > > chip = gpiod.Chip(c) > > for l in range(32): > > line = chip.get_line(l) > > if pin in line.name(): > > print("Found: ", line.name()) > > return > > else: > > raise ValueError("Can't find pin '" + pin + "'") > > You don't store the line anywhere. > You need to use self.line > self.line = chip.get_line(l) > if pin... > > > def print_name(self): > > print (self.line.name()) > > > > def set(self): > > self.line.set_value(1) > > > > def clear(self): > > self.line.set_value(0) > > As you do here. > Yes, OK, absolutely. However that wasn't my original rather basic problem which was, as I said, that I wasn't running the code I was looking at. The above was just a quick hack from some even cruder code doing the same job, trying to develop it into something better and more general. It's all on a headless Beaglebone Black (bit like a Raspberry Pi) so I'm doing everything via multiple ssh connections and sometimes this results in "the left hand not knowing what the right hand is doing"! -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Finding good documentation for gpiod
I am using the gpiod package for manipulating GPIO inputs/outputs on a Beaglebone Black SBC (like a Raspberry Pi but with more flexible I/O). Mostly I am managing to get things to work as I want but better documentation of gpiod would be a great help. For example, when one has found an I/O pin (a 'line' in GPIO parlance) that one wants to use one has to 'request' it using the Line.request() method. The help for this is as follows:- Help on method_descriptor: request(...) request(consumer[, type[, flags[, default_val]]]) -> None Request this GPIO line. consumer Name of the consumer. type Type of the request. flags Other configuration flags. default_val Default value of this line. Note: default_vals argument (sequence of default values passed down to LineBulk.request()) is still supported for backward compatibility but is now deprecated when requesting single lines. Which is pretty good **except** that I can't find a proper description of the parameters anywhere, i.e. there's nowhere that even tells me what types of values/objects the parameters are. At the end of the gpiod.Line section of the help there is this:- | ACTIVE_HIGH = 1 | | ACTIVE_LOW = 2 | | BIAS_AS_IS = 1 | | BIAS_DISABLE = 2 | | BIAS_PULL_DOWN = 4 | | BIAS_PULL_UP = 3 | | DIRECTION_INPUT = 1 | | DIRECTION_OUTPUT = 2 Which **might** be appropriate values for 'type' or 'flags' but there doesn't seem to be any way of knowing. Am I missing something very obvious somewhere? Is there a 'standard' way of finding out parameter information? It may well be that I'm simply banging up against the limit of what documentation is available, I have managed to get code working OK. It's just that I'd be happier if I really know what I was doing! :-) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Is a Python event polled or interrupt driven?
In the following code is the event polled by the Python process running the code or is there something cleverer going on such that Python sees an interrupt when the input goes high (or low)? import Adafruit_BBIO.GPIO as GPIO Pin = "P8_8" GPIO.setup(Pin, GPIO.IN)# set GPIO25 as input (button) def my_callback(channel): if GPIO.input(Pin): print "Rising edge detected on 25" else: # if port 25 != 1 print "Falling edge detected on 25" GPIO.add_event_detect(Pin, GPIO.BOTH, my_callback, 1) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Is a Python event polled or interrupt driven?
Chris Angelico wrote: > On Fri, 13 Oct 2023 at 01:48, Chris Green via Python-list > wrote: > > > > In the following code is the event polled by the Python process > > running the code or is there something cleverer going on such that > > Python sees an interrupt when the input goes high (or low)? > > > > This isn't something inherent to Python; it's the specific behaviour > of the library you're using. So I dug through that library a bit, and > ended up here: > > https://github.com/adafruit/adafruit-beaglebone-io-python/blob/cf306ed7f9f24111d0949dd60ac232e81241bffe/source/event_gpio.c#L753 > > > > which starts a thread: > > https://github.com/adafruit/adafruit-beaglebone-io-python/blob/cf306ed7f9f24111d0949dd60ac232e81241bffe/source/event_gpio.c#L662 > > > > which appears to make use of epoll for efficient event handling. Edge > detection itself seems to be done here: > > https://github.com/adafruit/adafruit-beaglebone-io-python/blob/cf306ed7f9f24111d0949dd60ac232e81241bffe/source/event_gpio.c#L522 > > > > I don't know enough about the architecture of the BeagleBone to be > certain, but my reading of it is that most of the work of edge > detection is done by the OS kernel, which then sends the Adafruit > handler a notification via a file descriptor. The secondary thread > waits for those messages (which can be done very efficiently), and in > turn calls the Python callbacks. > > In other words, the "something cleverer" is all inside the OS kernel, > and yes, in effect, it's an interrupt. > Wow! Thanks for doing all that research. It sounds as if it may be more efficient than I thought so may be fast enough. I guess I'll just have to try some actual code (and hardware) and see how it goes. Thanks again! -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
How to find any documentation for smbus?
I am using the python3 smbus module, but it's hard work because of the lack of documentation. Web searches confirm that the documentation is somewhat thin! If you do the obvious this is what you get:- >>> import smbus >>> dir (smbus) ['SMBus', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] >>> help(smbus) Help on module SMBus: NAME SMBus DESCRIPTION This module defines an object type that allows SMBus transactions on hosts running the Linux kernel. The host kernel must have I2C support, I2C device interface support, and a bus adapter driver. All of these can be either built-in to the kernel, or loaded from modules. Because the I2C device interface is opened R/W, users of this module usually must have root permissions. FILE /usr/lib/python3/dist-packages/smbus.cpython-39-arm-linux-gnueabihf.so Even a list of available methods would be handy! :-) Presumably python3's smbus is just a wrapper so if I could find the underlying C/C++ documentation it might help. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How to find any documentation for smbus?
km wrote: > Il Sat, 28 Oct 2023 17:08:00 +0100, Chris Green ha scritto: > > > I am using the python3 smbus module, but it's hard work because of the > > lack of documentation. Web searches confirm that the documentation is > > somewhat thin! > > > > If you do the obvious this is what you get:- > > > > >>> import smbus dir (smbus) > > ['SMBus', '__doc__', '__file__', '__loader__', '__name__', > > '__package__', '__spec__'] > > >>> help(smbus) > > > > > > Help on module SMBus: > > > > NAME > > SMBus > > > > DESCRIPTION > > This module defines an object type that allows SMBus > > transactions on hosts running the Linux kernel. The host kernel > > must have I2C support, I2C device interface support, and a bus > > adapter driver. > > All of these can be either built-in to the kernel, or loaded > > from modules. > > > > Because the I2C device interface is opened R/W, users of this > > module usually must have root permissions. > > > > FILE > > /usr/lib/python3/dist-packages/smbus.cpython-39-arm-linux- > gnueabihf.so > > > > > > Even a list of available methods would be handy! :-) > > > > > > Presumably python3's smbus is just a wrapper so if I could find the > > underlying C/C++ > > documentation it might help. > > https://pypi.org/project/smbus2/ > > smbus2 is designed to be a "drop-in replacement of smbus". SO you can look > at its documentation for or use it instead of smbus. > > Disclaimer: I haven't any experience on this library Ah, thank you, I had come across smbus2 but wanted to stay with smbus if I could as it's in the Debian repositories. However, as you say, it claims to be a "drop-in replacement of smbus" so the documentation should be some help at least. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How to find any documentation for smbus?
Dan Purgert wrote: > On 2023-10-28, Chris Green wrote: > > I am using the python3 smbus module, but it's hard work because of the > > lack of documentation. Web searches confirm that the documentation is > > somewhat thin! > > > > The SMBus spec is available from http://smbus.org (or at least it used > to be ... watch it be hidden behind a paywall now). > That provides very detailed hardware information but virtually nothing at all about software libraries and such. Lots of interesting reading, for example there's an appendix detailing the differences between smbus and i2c, but nothing very helpful for a poor old application programmer like me! :-) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
pip/pip3 confusion and keeping up to date
I have a couple of systems which used to have python2 as well as python3 but as Ubuntu and Debian verions have moved on they have finally eliminated all dependencies on python2. So they now have only python3 and there is no python executable in PATH. There's still both /usr/bin/pip and /usr/bin/pip3 but they're identical so presuably I can now simply use pip and it will be a python3 pip. So, going on from this, how do I do the equivalent of "apt update; apt upgrade" for my globally installed pip packages? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Jon Ribbens wrote: > On 2023-11-02, Dieter Maurer wrote: > > Chris Green wrote at 2023-11-2 10:58 +: > >> ... > >>So, going on from this, how do I do the equivalent of "apt update; apt > >>upgrade" for my globally installed pip packages? > > > > `pip list -o` will tell you for which packages there are upgrades > > available. > > `pip install -U ...` will upgrade packages. > > > > Be careful, though. > > With `apt`, you usually have (`apt`) sources representing a consistent > > package universe. Someone tests that package upgrades in this > > universe do not break other packages (in this universe). > > Because of this, upgrading poses low risk. > > > > `PyPI` does not guarantes consistency. A new package version > > may be incompatible to a previous one -- and with other > > package you have installed. > > > > I do not think that you would want to auto-upgrade all installed > > packages. > > Indeed. What you're describing is a very unfortunate failing of pip. > 'Upgrade' doesn't even follow requirements when you tell it what to > upgrade - e.g. if you do "pip install foo" and foo requires "bar<2" > so you end up with: > >PackageVersion >-- - >foo1.0.0 >bar1.2.0 > > and then a new version 1.3.0 of bar comes out and you do > "pip install -U foo", pip will not upgrade bar even though it could > and should, because foo is already at the latest version so pip won't > even look at its dependencies. > > Indeed there is no way of knowing that you should upgrade bar without > manually following all the dependency graphs. ("pip list -o" will tell > you there's a newer version, but that isn't the same - e.g. if the new > version of bar was 2.0.0 then "pip list -o" will list it, but you should > not upgrade to it.) > > You can do "pip install -I foo", which will pointlessly reinstall foo > and then presumably upgrade bar as well, thus probably getting to the > right result via a rather roundabout route, but I'm not sure if that > does indeed work properly and if it is a reliable and recommended way > of doing things. It is a bit of a minefield isn't it. I try to minimise my use of packages installed using pip for this very reason. Maybe the safest route would simply be to uninstall everything and then re-install it. · -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Jon Ribbens wrote: > On 2023-11-02, Chris Green wrote: > > I have a couple of systems which used to have python2 as well as > > python3 but as Ubuntu and Debian verions have moved on they have > > finally eliminated all dependencies on python2. > > > > So they now have only python3 and there is no python executable in > > PATH. > > > > There's still both /usr/bin/pip and /usr/bin/pip3 but they're > > identical so presuably I can now simply use pip and it will be a > > python3 pip. > > > > > > So, going on from this, how do I do the equivalent of "apt update; apt > > upgrade" for my globally installed pip packages? > > I'm not sure what that question has to do with everything that preceded > it, but you don't want to install python packages globally using pip. > Either install them with 'apt', or install them in a virtual environment. Why in a virtual environment? When I install a package whether from apt or from pip I want everyone/everything on my system to be able to use it. I do only install a few things using pip. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Jon Ribbens wrote: > On 2023-11-02, Chris Green wrote: > > Jon Ribbens wrote: > >> On 2023-11-02, Chris Green wrote: > >> > I have a couple of systems which used to have python2 as well as > >> > python3 but as Ubuntu and Debian verions have moved on they have > >> > finally eliminated all dependencies on python2. > >> > > >> > So they now have only python3 and there is no python executable in > >> > PATH. > >> > > >> > There's still both /usr/bin/pip and /usr/bin/pip3 but they're > >> > identical so presuably I can now simply use pip and it will be a > >> > python3 pip. > >> > > >> > > >> > So, going on from this, how do I do the equivalent of "apt update; apt > >> > upgrade" for my globally installed pip packages? > >> > >> I'm not sure what that question has to do with everything that preceded > >> it, but you don't want to install python packages globally using pip. > >> Either install them with 'apt', or install them in a virtual environment. > > > > Why in a virtual environment? When I install a package whether from > > apt or from pip I want everyone/everything on my system to be able to > > use it. > > Because pip barely plays well by itself, let alone with other package > managers at the same time. > Well that's a criticism of pip rather than of how I use it! :-) OK, there are risks. > > I do only install a few things using pip. > > Are they not available in your system's package manager? > I guess you might get away with "sudo -H pip install -U foo" > for a couple of things, if they don't have many dependencies. I obviously check the package manager and also other sources which work through apt before resorting to using pip. The sort of thing I have to use pip for is software for odd I2C sensor devices and such. These rarely have any dependencies or they are all the same dependencies as the other I2C device software. So, hopefully, I won't hit any big problems. I have to say that so far I haven't been bitten. I would point out that this is mostly for a headless Beaglebone Black single board computer (comparable with a Raspberry Pi) with only a minimal 'console' installation of Debian so it's a pretty minimal system. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Jon Ribbens wrote: > On 2023-11-03, Karsten Hilbert wrote: > > Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via > > Python-list: > >> >So they now have only python3 and there is no python executable in > >> >PATH. > >> > >> FWIW, for this you install the little stub package python-is-python3. > >> Especially if you want to keep a python2 installation around - > >> "python" will still be python3 in this case. > > > > Since you seem knowledgeable in this area: Do you know of a > > resource for learning the *canonical* way of packaging a > > Python application for installation via apt which > > > > - needs some packages available via apt > > - needs some packages only available via pip > > - needs some packages newer than what is available via apt > > > > ? > > I suspect the answer to that is that you would have to: > > * create packages yourself for the unpackaged dependencies > * create a dependency graph of *every* Python package in the package > repository (whether or not the package is relevant to what you're doing) > * work out what versions of every Python package are required in order > to have a dependency graph that can be successfully resolved, taking > into account the requirements of your new package also > * contact every single maintainer of every single one of the packages > that needs updating and persuade them to update their packages and > reassure them that you are getting all the other package maintainers > to update their packages accordingly and that you have a plan and > that you know what you're doing > > ... screen fades to black, title card "3 years later", fade in to ... > > * publish your package > Surely it's not that bad, the vast bulk of Debian, Ubuntu and other distributions are installed via systems that sort out dependencies once given a particular package's requirements. Python is surely not unique in its dependency requirements. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Silly/crazy problem with sqlite
This is driving me crazy, I'm running this code:- #!/usr/bin/env python3 # # # Show the electric fence history, default to last 24 hours # import sqlite3 import datetime import sys today = datetime.datetime.now() today = str(today) x = str(today[0:10]) print(x) fdb = sqlite3.connect("/home/chris/.share/newbourne.db") cr = fdb.cursor() sql = "SELECT * FROM fence where datetime LIKE ?" cr.execute(sql, ('%' + "2023-11" + '%')) rv = cr.fetchall() for d in rv: print(d) fdb.commit() fdb.close() Forget about the 'today =' bits, they no longer do anything. When I run the above I get:- chris@esprimo$ fence.py 2023-11-24 Traceback (most recent call last): File "/home/chris/dev/bin/fence.py", line 19, in cr.execute(sql, ('%' + "2023-11" + '%')) sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied. chris@esprimo$ It's treating the "2023-11" plus % at each end as separate variables to the binding, this is crazy! I've done similar elsewhere and it works OK, what on earth am I doing wrong here? It has to be something very silly but I can't see it at the moment. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Silly/crazy problem with sqlite
Chris Green wrote: > This is driving me crazy, I'm running this code:- OK, I've found what's wrong:- > cr.execute(sql, ('%' + "2023-11" + '%')) should be:- cr.execute(sql, ('%' + x + '%',) ) I have to say this seems very non-pythonesque to me, the 'obvious' default simply doesn't work right, and I really can't think of a case where the missing comma would make any sense at all. Maybe I've had too much to eat and drink tonight! :-) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Silly/crazy problem with sqlite
Stefan Ram wrote: > Chris Green writes: > >I have to say this seems very non-pythonesque to me, the 'obvious' > >default simply doesn't work right, and I really can't think of a case > >where the missing comma would make any sense at all. > > |6.15 Expression lists > ... > |an expression list containing at least one comma yields a tuple. > ... > The Python Language Reference, Release 3.13.0a0; > Guido van Rossum and the Python development team; > October 10, 2023. > I wasn't meaning that it wasn't correct Python, more that doing the obvious doesn't work which, in Python, it usually does in my experience. The error message could be a bit more helpful too, maybe one of those "... did you mean ?" ones could point one in the right direction. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
How/where to store calibration values - written by program A, read by program B
Is there a neat, pythonic way to store values which are 'sometimes' changed? My particular case at the moment is calibration values for ADC inputs which are set by running a calibration program and used by lots of programs which display the values or do calculations with them. From the program readability point of view it would be good to have a Python module with the values in it but using a Python program to write/update a Python module sounds a bit odd somehow. I could simply write the values to a file (or a database) and I suspect that this may be the best answer but it does make retrieving the values different from getting all other (nearly) constant values. Are there any Python modules aimed specifically at this sort of requirement? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How/where to store calibration values - written by program A, read by program B
Thomas Passin wrote: > On 12/5/2023 11:50 AM, MRAB via Python-list wrote: > > On 2023-12-05 14:37, Chris Green via Python-list wrote: > >> Is there a neat, pythonic way to store values which are 'sometimes' > >> changed? > >> > >> My particular case at the moment is calibration values for ADC inputs > >> which are set by running a calibration program and used by lots of > >> programs which display the values or do calculations with them. > >> > >> From the program readability point of view it would be good to have a > >> Python module with the values in it but using a Python program to > >> write/update a Python module sounds a bit odd somehow. > >> > >> I could simply write the values to a file (or a database) and I > >> suspect that this may be the best answer but it does make retrieving > >> the values different from getting all other (nearly) constant values. > >> > >> Are there any Python modules aimed specifically at this sort of > >> requirement? > >> > > Some kind of key/value store sounds like the correct solution. I > > wouldn't go as far a database - that's overkill for a few calibration > > values. > > > > I might suggest TOML, except that Python's tomllib (Python 3.11+) is > > read-only! > > > > Personally, I'd go for lines of: > > > > key1: value1 > > key2: value2 > > > > Simple to read, simple to write. > > Just go with an .ini file. Simple, well-supported by the standard > library. And it gives you key/value pairs. > My requirement is *slightly* more complex than just key value pairs, it has one level of hierarchy, e.g.:- KEY1: a: v1 c: v3 d: v4 KEY2: a: v7 b: v5 d: v6 Different numbers of value pairs under each KEY. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How/where to store calibration values - written by program A, read by program B
Paul Rubin wrote: > Chris Green writes: > > I could simply write the values to a file (or a database) and I > > suspect that this may be the best answer but it does make retrieving > > the values different from getting all other (nearly) constant values. > > I've used configparser for this, though its intention is files that are > manually edited, rather than updated by a program. > > You can also read and dump a json file or pickle file. I prefer json to > pickle for most purposes these days. > > I don't like YAML and I don't like the proliferation of markup formats > of this type. So while I don't know exactly what TOML is, I figure it > must be bad. > > I sometimes use ast.literal_eval though it is Python specific. > That's interesting, I'll add it to my armoury anyway. :-) > Of course there is also sqlite but that is probably overkill. It's what my current code uses but does feel a bit OTT and it isn't particularly convenient to view when debugging. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How/where to store calibration values - written by program A, read by program B
Thank you everyone for all the suggestions, I now have several possibilities to follow up. :-) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
How to enter multiple, similar, dictionaries?
Is there a way to abbreviate the following code somehow? lv = {'dev':'bbb', 'input':'1', 'name':'Leisure volts'} sv = {'dev':'bbb', 'input':'0', 'name':'Starter volts'} la = {'dev':'bbb', 'input':'2', 'name':'Leisure Amps'} sa = {'dev':'bbb', 'input':'3', 'name':'Starter Amps'} bv = {'dev':'adc2', 'input':0, 'name':'BowProp Volts'} It's effectively a 'table' with columns named 'dev', 'input' and 'name' and I want to access the values of the table using the variable name. I could, obviously, store the data in a database (sqlite), I have some similar data in a database already but the above sort of format in Python source is more human readable and accessible. I'm just looking for a less laborious way of entering it really. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How to enter multiple, similar, dictionaries?
Chris Green wrote: > Is there a way to abbreviate the following code somehow? > > lv = {'dev':'bbb', 'input':'1', 'name':'Leisure volts'} > sv = {'dev':'bbb', 'input':'0', 'name':'Starter volts'} > la = {'dev':'bbb', 'input':'2', 'name':'Leisure Amps'} > sa = {'dev':'bbb', 'input':'3', 'name':'Starter Amps'} > bv = {'dev':'adc2', 'input':0, 'name':'BowProp Volts'} > > It's effectively a 'table' with columns named 'dev', 'input' and > 'name' and I want to access the values of the table using the variable > name. > Or, more sensibly, make the above into a list (or maybe dictionary) of dictionaries:- adccfg = [ {'abbr':'lv', 'dev':'bbb', 'input':'1', 'name':'Leisure volts'}, {'abbr':'sv', 'dev':'bbb', 'input':'0', 'name':'Starter volts'}, {'abbr':'la', 'dev':'bbb', 'input':'2', 'name':'Leisure Amps'}, {'abbr':'sa', 'dev':'bbb', 'input':'3', 'name':'Starter Amps'}, {'abbr':'bv', 'dev':'adc2', 'input':0, 'name':'BowProp Volts'} ] This pickles nicely, I just want an easy way to enter the data! > I could, obviously, store the data in a database (sqlite), I have some > similar data in a database already but the above sort of format in > Python source is more human readable and accessible. I'm just looking > for a less laborious way of entering it really. > -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How to enter multiple, similar, dictionaries?
Jon Ribbens wrote: > On 2023-12-11, Chris Green wrote: > > Chris Green wrote: > >> Is there a way to abbreviate the following code somehow? > >> > >> lv = {'dev':'bbb', 'input':'1', 'name':'Leisure volts'} > >> sv = {'dev':'bbb', 'input':'0', 'name':'Starter volts'} > >> la = {'dev':'bbb', 'input':'2', 'name':'Leisure Amps'} > >> sa = {'dev':'bbb', 'input':'3', 'name':'Starter Amps'} > >> bv = {'dev':'adc2', 'input':0, 'name':'BowProp Volts'} > >> > >> It's effectively a 'table' with columns named 'dev', 'input' and > >> 'name' and I want to access the values of the table using the variable > >> name. > >> > > Or, more sensibly, make the above into a list (or maybe dictionary) > > of dictionaries:- > > > > adccfg = [ > > {'abbr':'lv', 'dev':'bbb', 'input':'1', 'name':'Leisure volts'}, > > {'abbr':'sv', 'dev':'bbb', 'input':'0', 'name':'Starter volts'}, > > {'abbr':'la', 'dev':'bbb', 'input':'2', 'name':'Leisure Amps'}, > > {'abbr':'sa', 'dev':'bbb', 'input':'3', 'name':'Starter Amps'}, > > {'abbr':'bv', 'dev':'adc2', 'input':0, 'name':'BowProp Volts'} > > ] > > > > This pickles nicely, I just want an easy way to enter the data! > > adccfg = [ > dict(zip(('abbr', 'dev', 'input', 'name'), row)) > for row in ( > ('lv', 'bbb', '1', 'Leisure volts'), > ('sv', 'bbb', '0', 'Starter volts'), > ('la', 'bbb', '2', 'Leisure Amps'), > ('sa', 'bbb', '3', 'Starter Amps'), > ('bv', 'adc2', 0, 'BowProp Volts'), > ) > ] Neat, I like that, thank you. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How/where to store calibration values - written by program A, read by program B
Peter J. Holzer wrote: > [-- text/plain, encoding quoted-printable, charset: us-ascii, 40 lines --] > > On 2023-12-29 09:01:24 -0800, Grant Edwards via Python-list wrote: > > On 2023-12-28, Peter J. Holzer via Python-list > > wrote: > > > On 2023-12-28 05:20:07 +, rbowman via Python-list wrote: > > >> On Wed, 27 Dec 2023 03:53:42 -0600, Greg Walters wrote: > > >> > The biggest caveat is that the shared variable MUST exist before it can > > >> > be examined or used (not surprising). > > >> > > >> There are a few other questions. Let's say config.py contains a variable > > >> like 'font' that is a user set preference or a calibration value > > >> calculated by A to keep with the thread title. Assuming both scripts are > > >> running, how does the change get propagated to B after it is set in A > > > > > > It isn't. The variable is set purely in memory. This is a mechanism to > > > share a value between multiple modules used by the same process, not to > > > share between multiple processes (whether they run the same or different > > > scripts) > > > > > >> and written to the shared file? > > > > > > Nothing is ever written to a file. > > > > Then how does it help the OP to propogate clibration values from one > > program to another or from one program run to the next run? > > It doesn't. See his second mail in this thread, where he explains it in > a bit more detail. I think he might be a bit confused in his > terminology. > If I am the OP (I suspect I may be) I have gone with JSON stored in a file to provide what I need. The Python json package is very simple to use and with an 'indent=' setting the resulting json is reasonably human readable which is all I need. Thus programs simply read the values from the json file into a dictionary of dictionaries and the 'updater of values' program can write them back after changes. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Can one output something other than 'nan' for not a number values?
I'm looking for a simple way to make NaN values output as something like '-' or even just a space instead of the string 'nan'. This would then make it much easier to handle outputting values from sensors when not all sensors are present. So, for example, my battery monitoring program outputs:- Battery Voltages and Currents Leisure Battery - 12.42 volts -0.52 Amps Starter Battery - 12.34 volts -0.01 Amps If the starter battery sensor has failed, or is disconnected, I see:- Battery Voltages and Currents Leisure Battery - 12.42 volts -0.52 Amps Starter Battery - nan voltsnan Amps What I would like is for those 'nan' strings to be just a '-' or something similar. Obviously I can write conditional code to check for float('nan') values but is there a neater way with any sort of formatting string or other sort of cleverness? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Can one output something other than 'nan' for not a number values?
dn wrote: > On 18/02/24 09:53, Grant Edwards via Python-list wrote: > > On 2024-02-17, Cameron Simpson via Python-list > > wrote: > >> On 16Feb2024 22:12, Chris Green wrote: > >>> I'm looking for a simple way to make NaN values output as something > >>> like '-' or even just a space instead of the string 'nan'. > >>> [...] > >>> > >>> Battery Voltages and Currents > >>> Leisure Battery - 12.42 volts -0.52 Amps > >>> Starter Battery - nan voltsnan Amps > >>> > >>> What I would like is for those 'nan' strings to be just a '-' or > >>> something similar. > > > >> The simplest thing is probably just a function writing it how you want > >> it: > >> > >> def float_s(f): > >> if isnan(f): > >> return "-" > >> return str(f) > >> > >> and then use eg: > >> > >> print(f'value is {float_s(value)}') > >> > >> or whatever fits your code. > > > > Except he's obviously using some sort of formatting to control the > > number of columns and decimal places, so 'str(f)' is not going to cut > > it. Is the basic floating point number formatting functionality seen > > when using f-strings or '%' operator part of the float type or is it > > part of the f-string and % operator? > > It's part of the PSL's string library: "Format Specification > Mini-Language" > https://docs.python.org/3/library/string.html#format-specification-mini-language > > Has the OP stated if we're talking 'Python' or numpy, pandas, ...? > Just python, on a Raspberry Pi, so currently Python 3.9.2. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Can one output something other than 'nan' for not a number values?
Grant Edwards wrote: > On 2024-02-16, Chris Green via Python-list wrote: > > > I'm looking for a simple way to make NaN values output as something > > like '-' or even just a space instead of the string 'nan'. > > It would probably help if you told us how you're "outputting" them now > (the Python feaatures/functions used, not the actual output format). > > Are you using f-strings, the % operator, str.format(), or ?? > > I would be tempted to try monkey-patching the float class to override > the __format__ method. I have no idea what side effects that might > have, or if it's even used by the various formatting mechanisms, so > you might end up scraping bits off the walls... > It's using f'{...}' at the moment. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Couldn't install numpy on Python 2.7
Chris Angelico wrote: > On Thu, 13 Jun 2024 at 10:58, wrote: > > > > Chris, > > > > You seem to have perceived an insult that I remain unaware of. > > If you're not aware that you're saying this, then don't say it. > Er, um, that really makes no sense! :-) How can one not say something that one isn't aware of saying? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Best (simplest) way to share data between processes
I have a Raspberry Pi in my boat that uses I2C to read a number of voltages and currents (using ADS1115 A2D) so I can monitor the battery condition etc. At present various different scripts (i.e. processes) just read the values using the I2C bus whenever they need to but I'm pretty sure this (quite rarely) results in false readings because two processes try to read at the same time. Thus I'm looking for ways to prevent simultaneous access. One fairly obvious way is to have single process/script which reads the A2D values continuously and writes them to a file. All other scripts then read from the file as needed, a simple file lock can then be used to prevent simultaneous access (well, simultaneous access when the writing process is writing). Is this the simplest approach? Are there better ways using multiprocess? (They look more complicated though). The I2C bus itself has a mutex but I don't think this guarantees that (for example) an A2D reading is atomic because one reading takes more than one I2C bus access. Would a mutex of some sort around each I2C transaction (i.e. complete A2D reading) be a better way to go? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Best (simplest) way to share data between processes
Piergiorgio Sartor wrote: > On 06/07/2024 09.28, Chris Green wrote: > > I have a Raspberry Pi in my boat that uses I2C to read a number of > > voltages and currents (using ADS1115 A2D) so I can monitor the battery > > condition etc. > > > > At present various different scripts (i.e. processes) just read the > > values using the I2C bus whenever they need to but I'm pretty sure > > this (quite rarely) results in false readings because two processes > > try to read at the same time. > > > > Thus I'm looking for ways to prevent simultaneous access. > > Why using "different scripts"? > Is it there any particular reason? > > Maybe it would be better, if possible, to have > a single script, which, sequentially, reads > whatever needs to be read (or written). > In a loop. > > This is even simpler than using a file. > Yes, but it's conceptually (and programming wise) much simpler to have separate scripts. Some of them are simple 'on demand' scripts that I run from the command line when I want to know something. Others are scripts that drive displays on control panels. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Best (simplest) way to share data (Posting On Python-List Prohibited)
Lawrence D'Oliveiro wrote: > On Sat, 6 Jul 2024 08:28:41 +0100, Chris Green wrote: > > > One fairly obvious way is to have single process/script which reads the > > A2D values continuously and writes them to a file. All other scripts > > then read from the file as needed, a simple file lock can then be used > > to prevent simultaneous access (well, simultaneous access when the > > writing process is writing). > > The thing with a file is, it persists even when the collector process is > not running. Do you want data that persists when the collector process is > not running? > > Is this a history of values, or just a snapshot of current values? A > history of values could be written to a database. Databases provide their > own transactions and interlocking to prevent readers from reading partial > updates. > There's a separate (crontab driven) process that writes the history to a sqlite3 database, > If it’s a snapshot of current values, that does not persist when the > collector process is not running, then why not just keep the data in the > memory of the collector process, and have it concurrently listen on a > socket for connections from readers requesting a copy of the current data? That's exactly the sort of solution I was wondering about. Is there a ready made module/library for handling this sort of thing? Basically it will just be a string of a few tens of characters that would be kept up to date by one process and asked for by all the others. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Best (simplest) way to share data
Stefan Ram wrote: > Chris Green wrote or quoted: > >That's exactly the sort of solution I was wondering about. Is there a > >ready made module/library for handling this sort of thing? Basically > >it will just be a string of a few tens of characters that would be > >kept up to date by one process and asked for by all the others. > > I'm not an expert here, and just quickly tried to make it > run, so the code will still contain errors and not contain > something necessary, but might give you a starting point. > > A process doing something (here: printing an incrementing value > named "info") and also serving requests from other processes > for this "info" value: > [snip] Thanks, that should get me started! :-) -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
How to manage accented characters in mail header?
I have a Python script that filters my incoming E-Mail. It has been working OK (with various updates and improvements) for many years. I now have a minor new problem when handling E-Mail with a From: that has accented characters in it:- From: Sébastien Crignon I use Python mailbox to parse the message:- import mailbox ... ... msg = mailbox.MaildirMessage(sys.stdin.buffer.read()) Then various mailbox methods to get headers etc. I use the following to get the From: address:- str(msg.get('from', "unknown").lower() The result has the part with the accented character wrapped as follows:- From: =?utf-8?B?U8OpYmFzdGllbiBDcmlnbm9u?= I know I have hit this issue before but I can't rememeber the fix. The problem I have now is that searching the above doesn't work as expected. Basically I just need to get rid of the ?utf-8? wrapped bit altogether as I'm only interested in the 'real' address. How can I easily remove the UTF8 section in a way that will work whether or not it's there? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: How to manage accented characters in mail header?
Stefan Ram wrote: > Chris Green wrote or quoted: > >From: =?utf-8?B?U8OpYmFzdGllbiBDcmlnbm9u?= > > In Python, when you roll with decode_header from the email.header > module, it spits out a list of parts, where each part is like > a tuple of (decoded string, charset). To smash these decoded > sections into one string, you’ll want to loop through the list, > decode each piece (if it needs it), and then throw them together. > Here’s a straightforward example of how to pull this off: > > from email.header import decode_header > > # Example header > header_example = \ > 'From: =?utf-8?B?U8OpYmFzdGllbiBDcmlnbm9u?= ' > > # Decode the header > decoded_parts = decode_header(header_example) > > # Kick off an empty list for the decoded strings > decoded_strings = [] > > for part, charset in decoded_parts: > if isinstance(part, bytes): > # Decode the bytes to a string using the charset > decoded_string = part.decode(charset or 'utf-8') > else: > # If it’s already a string, just roll with it > decoded_string = part > decoded_strings.append(decoded_string) > > # Join the parts into a single string > final_string = ''.join(decoded_strings) > > print(final_string)# From: Sébastien Crignon > > Breakdown > > decode_header(header_example): This line takes your email header > and breaks it down into a list of tuples. > > Looping through decoded_parts: You check if each part is in > bytes. If it is, you decode it using whatever charset it’s > got (defaulting to 'utf-8' if it’s a little vague). > > Appending Decoded Strings: You toss each decoded part into a list. > > Joining Strings: Finally, you use ''.join(decoded_strings) to glue > all the decoded strings into a single, coherent piece. > > Just a Heads Up > > Keep an eye out for cases where the charset might be None. In those > moments, it’s smart to fall back to 'utf-8' or something safe. > Thanks, I think! :-) Is there a simple[r] way to extract just the 'real' address between the <>, that's all I actually need. I think it has the be the last chunk of the From: doesn't it? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Tools to help with text mode (i.e. non-GUI) input
I'm looking for Python packages that can help with text mode input, i.e. for use with non-GUI programs that one runs from the command prompt in a terminal window running a bash shell or some such. What I'm specifically after is a way to provide a default value that can be accepted or changed easily and also a way to provide a number of different values to choose from. I.e. for the default sort of input one might see:- Colour? red Hitting return would return 'red' to the program but you could also backspace over the 'red' and enter something else. Maybe even better would be that the 'red' disappears as soon as you hit any key other than return. For the select a value type of input I want something like the above but hitting (say) arrow up and arrow down would change the value displayed by the 'Colour?' prompt and hitting return would accept the chosen value. In addition I want the ability to narrow down the list by entering one or more initial characters, so if you enter 'b' at the Colour? prompt the list of values presented would only include colours starting with 'b' (beige, blue, black, etc.) Are there any packages that offer this sort of thing? I'd prefer ones from the Debian repositories but that's not absolutely necessary. It might also be possible/useful to use the mouse for this. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Using pipx for packages as opposed to applications
Can one use pipx to wrap the process of creating an independent environment for a python package as opposed to a runnable application? E.g. I want to install and use pksheet but, as it's not available from the Debian repositories, I'll have to install it from PyPi. So I should put it in its own environment. Can pipx help me with this? -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Strategies for avoiding having to use --break-system-packages with pip
Peter J. Holzer wrote: > [-- text/plain, encoding quoted-printable, charset: us-ascii, 32 lines --] > > On 2025-01-14 11:32:35 +0000, Chris Green via Python-list wrote: > > Use a virtual environment, what do I have to do then to make using > > my program (that uses tkintertable) 'transparent', i.e. I just > > want to be able to run the program from the command prompt like > > any other program. > > Just use the python interpreter in the venv in the hashbang line. > > For example, here's the first line of one my scripts: > > #!/usr/local/share/wds/venv/bin/python3 > > As you can probably guess, the venv is in /usr/local/share/wds/venv. > > There is no need for wrapper scripts which activate the venv. Python > does that all by itself. > > I have a small script, install-python[1], to assist with setting the > hashbang, but if it's just a few scripts you can simply edit it manually. > OP here. Yes, thank you, I thought that the shebang line would do the trick but it's nioce to have it confirmed. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Using pipx for packages as opposed to applications
Stefan Ram wrote: > Chris Green wrote or quoted: > >E.g. I want to install and use pksheet but, as it's not available from > >the Debian repositories, I'll have to install it from PyPi. > > I can't dig up any "pksheet" on PyPI. So, you got to take > my earlier response like a rumor from a random tech meetup in > Palo Alto - sounds interesting, but needs serious verification. > Ah, oops, a typo. It's pysheet (I have pk on the brain from it being Point Kilometrique, distance markers on canals in France). Thanks for your previous response, it told me what I needed to know, that pipx isn't really going to do what I want particularly easily. If I DIY an environment for pysheet and then develop some python that uses it, how do I then make it accessible as a 'normal' program? This is just for my own use by the way, on (probably) just a couple of Linux systems. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Tools to help with text mode (i.e. non-GUI) input
rustbuck...@nope.com wrote: > > This is what I was going to suggest. Rich is super easy to use. OK, thanks, Rich is on my shortlist then. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Tools to help with text mode (i.e. non-GUI) input
Alan Gauld wrote: > On 14/01/2025 00:20, Grant Edwards via Python-list wrote: > > On 2025-01-13, Alan Gauld via Python-list wrote: > > > >> All of that is possible in curses, you just have to code it. > > > > All of that is easy with curses in C. Unfortunately, the high level > > "panel" and "menu" curses subystems that make it easy aren't included > > in the Python curses API, > > panel is included. Just import curses.panel. > > menu unfortunately isn't but it's not difficult to roll > your own by creating a window with a list of options, provided > you don't try to get too fancy(submenus etc). > Yes, thanks all, maybe just straightforward curses is the way to go. Looking at some of the 'cleverer' ones they end up looking remarkably like GUI code, in which case I might as well use a GUI. I have written a (fairly simple) Gtk based python program, I was just trying to avoid all the GUI overheads for a little new project. -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Strategies for avoiding having to use --break-system-packages with pip
I have a (relatively) clean Debian 12 installation running on my two workhorse systems, a desktop server at home and my laptop that travels around with me. I moved from Xubuntu to Debian on both these systems a few months ago. I ran Xubuntu for many years and acquired a whole lot of python packages installed with pip, as root. For the last couple of years I had to use the --break-system-packages option to get things installed. As far as I'm aware I never hit any dependency problems doing this. It's probably because things I installed with pip were mostly quite small, specialised, packages that I used in just one or two utility programs that I had written myself. In quite a few cases these were realated to image processing and such things. So far I've managed to keep my Debian 12 installations 'pip free', I haven't even got pip installed. However I may have just come across something that would at least be very useful and it comes from PyPi. (It's tkintertable if that's of any interest or relevance) What are my options? Just install it using pip as root and --break-system-packages, what's likely to break? Use a virtual environment, what do I have to do then to make using my program (that uses tkintertable) 'transparent', i.e. I just want to be able to run the program from the command prompt like any other program. Download tkintertable from git into my development environment and use that. My PYTHONPATH will need to point to it but I can't see any further issues with doing this. Anything else? As far as I can see using pipx doesn't help me at all (see recent thread here). -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list
Re: Python List is Not Dead
Cameron Simpson wrote: > On 25Dec2024 14:52, Abdur-Rahmaan Janhangeer wrote: > >I have been following discussions on Discourse (discuss.python.org) > >these last times. > > > >I think that it definitely lacks some of the joys of the mailing list: > > FYI, it has a very good "mailing list" mode. I use it that was >90% of > the time, and file both posts from Discourse and posts from python-list > into my "python" mail folder. Yes, it's the one saving grace of a Discourse forum, you can use it by E-Mail and it behaves quite nicely with a text mode E-Mail client such as mutt so you can keep threads separate, follow sub-threads, etc. Not quite as good as this list gatewayed to usenet though, there's really nothing so good as usenet for proper discourse (!). -- Chris Green · -- https://mail.python.org/mailman/listinfo/python-list