Re: Python 3.8 or later on Debian?

2024-09-18 Thread dn via Python-list

On 19/09/24 02:49, Ulrich Goebel via Python-list wrote:

Hi,

Debian Linux seems to love Python 3.7 - that is shown by apt-get list, and it's 
installed on my Debian Server.

But I need at least Python 3.8

Is there a repository which I can give to apt to get Python 3.8 or later?

Or do I really have to install and compile these versions manually? I'm not a 
friend of things so deep in the system...



Assumptions:
1 "need" for a particular project, cf system-wide
2 use of a virtual-environment for project(s)


Try pyenv (https://github.com/pyenv/pyenv).

It offers a list of Python versions. When downloaded, it builds a 
version for you - assuming have build-environment s/w in place.

(this is where my lack of Debian knowledge may become obvious)

Thereafter, within the project's virtual-environment can select which 
(installed-version of) Python is to be used.


Am sure there are plenty of how-to-installs. Here's one:
https://bgasparotto.com/install-pyenv-ubuntu-debian

Am using pyenv to support multiple projects initially built during the 
reign of multiple Python versions (which now update annually - next is 
about two weeks away).


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Crash when launching python

2024-09-04 Thread dn via Python-list

On 5/09/24 03:27, Guenther Sohler via Python-list wrote:

Hi,

My "Project" is to integrate python support into OpenSCAD.  It runs quite
well, but
there are still issues on MacOS. On My MacOS it works, but it crashes when
I ship
the DMG files.
It looks very much like python is not able to find the "startup" python
files and therefore crashes.

Is it possible to turn on debugging and  to display on the console, where
python is loading files from ?



(am not a Mac user)

Starting with 'the basics', are you familiar with:
5. Using Python on a Mac https://docs.python.org/3/using/mac.html
(and the more general preceding sections)

This doc likely includes mention of such parameters:
1.2. Environment variables 
https://docs.python.org/3/using/cmdline.html#environment-variables


Here is a library for programmatic manipulation:
site — Site-specific configuration hook 
https://docs.python.org/3/library/site.html#module-site


Please let us know how things progress...

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Formatting a str as a number - Okay, one more related thing...

2024-09-01 Thread dn via Python-list

On 1/09/24 06:55, MRAB via Python-list wrote:

On 2024-08-31 06:31, Gilmeh Serda via Python-list wrote:

On Fri, 30 Aug 2024 05:22:17 GMT, Gilmeh Serda wrote:


f"{int(number):>20,}"


I can find "," (comma) and I can find "_" (underscore) but how about " "
(space)?

Or any other character, for that matter?

Any ideas?

Of course I can do f"{123456:>20_}".replace("_", " "), just thought there
might be something else my search mojo fails on.


The format is described here:

https://docs.python.org/3/library/string.html#formatspec

A space is counted as a fill character.



Rather than strict formatting, you may be venturing into 
"internationalisation/localisation" thinking.


Different cultures/languages present numeric-amounts in their own ways. 
For example, a decimal point may look like a dot or period to some 
(there's two words for the same symbol from different English-language 
cultures!), whereas in Europe the symbol others call a comma is used, eg 
123.45 or 123,45 - and that's just one complication of convention...


For your reading pleasure, please review "locales" 
(https://docs.python.org/3/library/locale.html)



Here's an example:

   Country Integer  Float
   USA 123,456 123,456.78
France 123 456 123 456,78
 Spain 123.456 123.456,78
  Portugal  123456  123456,78
Poland 123 456 123 456,78


Here's some old code, filched from somewhere (above web.ref?) and 
updated today to produce the above:-


""" PythonExperiments:locale_numbers.py
Demonstrate numeric-presentations in different cultures (locales).
"""

__author__ = "dn, IT&T Consultant"
__python__ = "3.12"
__created__ = "PyCharm, 02 Jan 2021"
__copyright__ = "Copyright © 2024~"
__license__ = "GNU General Public License v3.0"

# PSL
import locale


locales_to_compare = [
( "USA", "en_US", ),
( "France", "fr_FR", ),
( "Spain", "es_ES", ),
( "Portugal", "pt_PT", ),
( "Poland", "pl_PL", ),
]

print( "\n   Country Integer  Float" )
for country_name, locale_identifier in locales_to_compare:
locale.setlocale( locale.LC_ALL, locale_identifier, )
print( F"{country_name:>10}", end="  ", )
print(
locale.format_string("%10d", 123456, grouping=True, ),
end="",
)
print( locale.format_string("%15.2f", 123456.78, grouping=True, ) )

--
Regards =dn

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


ListAdmin: Is list/archive working correctly?

2024-08-30 Thread dn via Python-list
For example, have been following the thread "Is there a better way? 
[combining f-string, thousands separator, right align]".



Me email (only) client shows a thread of 12 messages.

The OP was @Gilmeh Serda (from an invalid email address). That appears 
in the email thread


@Stefan Ram has had two contributions quoted, but no such 
original-message has appeared in the thread.



The archive is only showing seven contributions (for some reason Grant's 
recent contribution under the different subject line: "Formatting a str 
as a number" appears separately, even though it threads as the same 
conversation in email)


None of the OP's contributions appear!


IIRC the design has been that it doesn't matter if a contribution comes 
from the Newsgroup or the email Discussion List, they are treated the 
same. Are Newsgroup contributions being archived (were they ever)?


Is it user-error that some contributions don't appear on the list, but 
do appear in replies, or is there perhaps some other cause?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Script stops running with no error

2024-08-28 Thread dn via Python-list

On 29/08/24 10:32, Thomas Passin via Python-list wrote:

On 8/28/2024 5:09 PM, Daniel via Python-list wrote:

As you all have seen on my intro post, I am in a project using Python
(which I'm learning as I go) using the wikimedia API to pull data from
wiktionary.org. I want to parse the json and output, for now, just the
definition of the word.

Wiktionary is wikimedia's dictionary.

My requirements for v1

Query the api for the definition for table (in the python script).
Pull the proper json
Parse the json
output the definition only



You need to check at each part of the code to see if you are getting or 
producing what you think you are.  You also should create a text 
constant containing the JSON input you expect to get.  Make sure you can 
process that.  Start simple - one main item.  Then two main items.  Then 
two main items with one sub item.  And so on.


I'm not sure what you want to produce in the end but this seems awfully 
complex to be starting with.  Also you aren't taking advantage of the 
structure inherent in the JSON.  If the data response isn't too big, you 
can probably take it as is and use the Python JSON reader to produce a 
Python data structure.  It should be much easier (and faster) to process 
the data structure than to repeatedly scan all those lines of data with 
regexes.



Good effort so far!


Further to @Thomas: the code does seem to be taking the long way around! 
How can we illustrate that, and improve life?



The Wiktionary docs at https://developer.wikimedia.org/use-content/ 
discuss how to use their "Developer Portal". Worth reading!


As part of the above, we find the "API:Data formats" page 
(https://www.mediawiki.org/wiki/API:Data_formats) which offers a simple 
example (more simple than your objectives):


api.php?action=query&titles=Main%20page&format=json

which produces:

{
  "query": {
"pages": {
  "217225": {
"pageid": 217225,
"ns": 0,
"title": "Main page"
  }
}
  }
}

Does this look like a Python dict[ionary's] output to you?

It is, (more discussion at the web.ref)
- but it is wrapped into a JSON payload.

There are various ways of dealing with JSON-formatted data. You're 
already using requests. Perhaps leave such research until later.



So, as soon as "page_data" is realised from "response", print() it (per 
above: make sure you're actually seeing what you're expecting to see). 
Computers have this literal habit of doing what we ask, not what we want!


PS the pprint/pretty printer library offers a neater way of outputting a 
"nested" data-structure (https://docs.python.org/3/library/pprint.html).



Thereafter, make as much use of the returned dict/list structure as can. 
At each stage of the 'drilling-down' process, again, print() it (to make 
sure ...)



In this way the code will step-through the various 'layers' of 
data-organisation. That observation and stepping-through of 'layers' is 
a hint that the code should (probably) also be organised by 'layer'! For 
example, the first for-loop finds a page which matches the search-key. 
This could be abstracted into a (well-named) function.


Thus, you can write a test-harness which provides the function with some 
sample input (which you know from earlier print-outs!) and can ensure 
(with yet another print()) that the returned-result is as-expected!


NB the test-data and check-print() should be outside the function. 
Please take these steps as-read or as 'rules'. Once your skills expand, 
you will likely become ready to learn about unit-testing, pytest, etc. 
At which time, such ideas will 'fall into place'.



BTW/whilst that 'unit' is in-focus: how many times will the current code 
compute search_query.lower()? How many times (per function call) will 
"search_query" be any different from previous calls? So, should that 
computation be elsewhere?
(won't make much difference to execution time, but a coding-skill: 
consider whether to leave computation until the result is actually 
needed (lazy-evaluation), or if early-computation will save unnecessary 
repeated-computation)



Similarly, 'lift' constants such as "cases" out of (what will become) 
functions and put them towards the top of the script. This means that 
all such 'definition' and 'configuration' settings will be found 
together in one easy-to-find location AND makes the functional code 
easier to read.



Now, back to the question: where is the problem arising? Do you know or 
do you only know that what comes-out at the end is 
unattractive/unacceptable?


The idea of splitting the code into functions (or "units") is not only 
that you could test each and thereby narrow-down the location of the 
problem (and so that we don't have to read so much code in a bid to 
help) but that when you do ask for assistance you will be able to 
provide only the pertinent code AND some sample input-data with 
expected-results!

(although, if all our dreams come true, you will answer your own question!)


OK, is tha

Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-26 Thread dn via Python-list

On 26/08/24 23:00, Dan Sommers via Python-list wrote:

On 2024-08-26 at 20:42:32 +1200,
dn via Python-list  wrote:


and if we really want to go over-board:


RIGHT_JUSTIFIED = ">"
THOUSANDS_SEPARATOR = ","
s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


or (better) because right-justification is the default for numbers:


s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"



To the extreme that if your user keeps fiddling with presentations (none
ever do, do they?), all settings to do with s_format could be added to a
config/environment file, and thus be even further separated from
program-logic!


And then you'll need a parser, many of whose Unique Challenges™ aren't
even apparent until you start parsing files from actual users, and
you'll still need some sort of fallback in the code anyway for the case
that s_format can't be parsed (for whatever reason).

Isn't a config file what just caused the global CrowdStrike outage?  ;-)

That said, I understand that report generators are a thing, not to
mention RPG (https://en.wikipedia.org/wiki/IBM_RPG).

Okay, sorry; I'll just crawl back into the hole from whence I came.



Not at all. Please continue to question/ask/suggest!

This is a valid point. There are costs and benefits (trade-offs) to all 
decisions!


That said, writing one's own parser would become a veritable can of 
worms/rabbit hole. Here be dragons!


Similarly, explaining this takes longer than writing the example itself!


Older Windows users will know about .ini files, and Linux Admins are 
familiar with .conf files. Many of us are already using JSON or YAML 
formats. Any of these (and more) could be pressed into service, as 
above. At the 'top end', there are also whole libraries devoted to 
establishing application configuration or "environments": default 
values, config files, command-line options, user-input...


Have switched to using Python-poetry, which replaces packaging methods 
such as setuptools (as well as virtual-environment tools). It takes its 
project configuration specifications from a pyproject.toml file. So, for 
a few projects lately, I've been using .toml for application-config as 
well. However, I have to say, this more from an attempt at consistency 
than a decision of logic. (critique welcome)


That said, a setup.py configuration, took the form:

setup(
name='demo_project',
version='1.1.0',
packages=find_packages(),
install_requires=[
'requests',
'numpy',
...
],
entry_points={
...

Accordingly, it offers an example of the simplest format (for us), and 
one which has a zero-learning pre-requisite. At execution-time, the 
moment such a config is import-ed, a syntax-error will immediately bring 
proceedings to a halt!



I have some stats-wonks as clients. They dabble in programming, but 
(fortunately) realise their limitations. (usually!) The boss has had to 
ban them from 'improving' my code ($paid to be an improvement on their 
usual quality), but including a .py configuration/options file has 
proven to be an honor-preserving compromise. Of course, they manage 
their own runs, adjusting parameters as they go. So, any errors are 
their own, and they can fix themselves (without anyone else knowing!).


Such would not work in many?most other environments - children: do not 
try this at home!



An irritation for those of us who have to delve into projects after 
they've been written, is a git-history full of the sorts of 
user-tweaking changes vilified earlier. Putting user-config into a 
separate file, even a separate sub-directory, makes it easy to spot 
which updates to ignore, and thus, which to consider!



PS the reason why CrowdStrike was not the end of humanity as we know it, 
(and only that of those who only know MSFT's eco-system) is because the 
majority of the world's Internet servers run Linux - including Azure 
(brings to mind the old saw: the package said "runs on Windows-95 or 
better" so I installed it on Linux!)


Joking aside, we (virtuous ones) ALWAYS test BEFORE release. Correct?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a better way? [combining f-string, thousands separator, right align]

2024-08-26 Thread dn via Python-list

On 26/08/24 03:12, Gilmeh Serda via Python-list wrote:

Subject explains it, or ask.

This is a bloody mess:


s = "123456789" # arrives as str
f"{f'{int(s):,}': >20}"

' 123,456,789'



With recent improvements to the expressions within F-strings, we can 
separate the string from the format required. (reminiscent of FORTRAN 
which had both WRITE and FORMAT statements, or for that matter HTML 
which states the 'what' and CSS the 'how')


Given that the int() instance-creation has a higher likelihood of 
data-error, it is recommended that it be a separate operation for ease 
of fault-finding - indeed some will want to wrap it with try...except.


>>> s = "123456789" # arrives as str
>>> s_int = int( s )  # makes the transformation obvious and distinct

>>> s_format = ">20,"  # define how the value should be presented

>>> F"{s_int:{s_format}}"
' 123,456,789'


Further, some of us don't like 'magic-constants', hence (previously):

>>> S_FIELD_WIDTH = 20
>>> s_format = F">{S_FIELD_WIDTH},"


and if we really want to go over-board:

>>> RIGHT_JUSTIFIED = ">"
>>> THOUSANDS_SEPARATOR = ","
>>> s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

or (better) because right-justification is the default for numbers:

>>> s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


To the extreme that if your user keeps fiddling with presentations (none 
ever do, do they?), all settings to do with s_format could be added to a 
config/environment file, and thus be even further separated from 
program-logic!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: new here

2024-08-25 Thread dn via Python-list

It appears there were some delays in the email/servers.
Thanks for this (and earlier) ideas and advice!


On 23/08/24 17:38, rbowman via Python-list wrote:

On Thu, 22 Aug 2024 19:56:54 -0700, Paul Rubin wrote:


With MicroPython on the Pico, you use some command line utility to
transfer files instead, but it is no big deal.


Loading the UF2 is easy.

https://www.raspberrypi.com/documentation/microcontrollers/
micropython.html

I use VS Code with the MicroPython extension so when the board is plugged
in it shows up as ttyACM0 or COM something I think on Windows. If you need
a package for a peripheral the file structure on the actually device shows
up so you can copy it to the lib directory.

https://pypi.org/project/pipkin/

pipkin is the command line utility. Thonny isn't my favorite IDE but it
does make life easy:

https://projects.raspberrypi.org/en/projects/getting-started-with-the-
pico/2


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: new here

2024-08-22 Thread dn via Python-list

On 23/08/24 15:43, rbowman via Python-list wrote:

On Fri, 23 Aug 2024 08:36:02 +1200, dn wrote:

On 23/08/24 07:49, rbowman via Python-list wrote:

On Thu, 22 Aug 2024 10:40:52 -0700, Paul Rubin wrote:


The Pico uses MicroPython which is stuck on an old version of Python,
unfortunately.


How did this enter the conversation/thread?

Paul's 'contribution' does not even appear on the Archive...


I'm probably guilty. I mentioned in passing the older protocols like
finger could even be implemented on something like the Pico W with
MicroPython.


The question arose because his message doesn't appear either in the 
conversation/email thread 'here', nor on the Archive. Perhaps not sent 
to the list?




I am confused by the cross-over to Python-list. I only read/post to
comp.lang.python. Is that echoed to Python-list or vice versa?


As I understand it, posts to 'the list' may be made at comp.lang.python 
or by email. Once on the server, messages are reflected back to both. 
Thus, Thunderbird is not set-up to use the newsgroup and keeps 
complaining at me when it's asked to reply to both. So, all 
contributions (from me) enter the server via email.




I haven't worked with CircuitPython lately and don't know if it has
pulled in later features.


Have you (gentle reader) used both and feel able to offer a comparison -
when to prefer one over the other?


I've only used CircuitPython on the Adafruit Playground Express.
https://circuitpython.org/board/circuitplayground_express/
and MicroPython on the Pico W. Since then Adafruit has expanded their
collection of boards and support them with CircuitPython.

One difference that makes them hard to compare is the Express has quite a
few on-board sensors like the Arduino Nano Sense 33, and interfaces to
them are baked into CircuitPython.

The Pico W has a wealth of I/O most doubling as I2C, PWM, or A/D with only
a onboard LED for the mandatory 'hello world' blink code. MicroPython is
more generic and you may have to import modules for specific external
devices like the SSD1306 OLED display. That's easily done with Thonny or
pipkin.


Adding a display to the Pico-W is my next project... After that, gyros 
(am thinking it may not go so well, on balance... hah!).


The Pico-W impresses. Its built-in Wi-Fi/Bluetooth capability makes life 
a lot easier (inside building use).


Apart from the earlier comment, my biggest frustration has come from the 
lack of facilities in Thonny compared with PyCharm - but will pick-up 
skills there, no doubt.


Conversely, (to having a separate radio-chip) I think I prefer the idea 
of being able to connect the Pico to whichever sensor(s) is/are 
actually-required. However, this is applied use - not learning or 'playing'.




As far as core Python I'd say they're similar. MicroPython is more generic
and may require more work to set up where Adafruit can match the boards
they have developed.

As I said it's been a while but MicroPython has the _threading module so
you can utilize both cores of the RP2040. Adafruit's new Feather has a
RP2040 and like the Pico W assumes you'll be using the PIO to externals
rather than anything onboard so CircuitPython probably has it.

https://www.adafruit.com/product/4884

 From the horse's mouth:

"There is great C/C++ support, unofficial (but really good) Arduino
support, an official MicroPython port, and a CircuitPython port! We of
course recommend CircuitPython because we think it's the easiest way to
get started and it has support with most of our drivers, displays,
sensors, and more, supported out of the box so you can follow along with
our CircuitPython projects and tutorials."


Whilst agreeing with the "easiest way to get started" claim, it probably 
also leads to the assumption that it will (later) be easier to run out 
of capability. Hence, that MicroPython would be the better professional 
option - assuming one already knows Python.


Yes, a degree of 'comparing apples with oranges' - and a 
continually-moving target!




I don't know if Adafruit has a RP2350 board yet but they say CircuitPython
will be even happier on the Pico 2.
https://www.adafruit.com/product/6006


No, out in the real-world, the Pico 2 is still vaporware.



For better or worse there are a lot more choices now than fiddling around
with the Arduino Uno back in the day.


True.
Hence the question.
Thanks for the comments!

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: new here

2024-08-22 Thread dn via Python-list

On 23/08/24 07:49, rbowman via Python-list wrote:

On Thu, 22 Aug 2024 10:40:52 -0700, Paul Rubin wrote:


The Pico uses MicroPython which is stuck on an old version of Python,
unfortunately.


How did this enter the conversation/thread?

Paul's 'contribution' does not even appear on the Archive...



I think it's up to 3.4 in general and erratic past that. It doesn't have
the match from 3.10.  I don't think it has f-strings though it may have
the walrus. There are workarounds but it can be annoying.


Two points:

- it's cut-down to work on bare-metal which makes for low demands on 
resources, but commensurate shortage of the facilities we CPython 
developers take for-granted (ie may allow ourselves to find annoying)


- it has f-strings, but frustrates those of us who prefer F-strings

- the docs point-out that (compared with full-fat Python) it is less 
consistent across environments. Accordingly, worth reading the "Quick 
Reference for [your processor]" sections of the docs, eg R-Pi Pico 
version only has half of the ADC-methods.



Once scale expectations to take into account the power of the processor, 
MicroPython goes-like-the-clappers!




I haven't worked with CircuitPython lately and don't know if it has pulled
in later features.


Have you (gentle reader) used both and feel able to offer a comparison - 
when to prefer one over the other?




[https://www.phrases.org.uk/meanings/like-the-clappers.html]
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: new here

2024-08-21 Thread dn via Python-list

On 22/08/24 09:15, Daniel via Python-list wrote:

rbowman  writes:


On Tue, 20 Aug 2024 23:26:39 +0100, Daniel wrote:


...

smolnet, as in things like


Lesser used protocols not known by many in the mainstream. Such as:

gopher, gemini, finger, spartan, titan, etc.

An example of use, here's a weather service tied to a finger. Put your
city name as the user. This isn't mine, but it is inspiring. Example:

finger mi...@graph.no


The OpSys on this machine no longer features finger (available for 
installation as an 'extra').


For Miami weather using a stock-standard web-browser, try: 
https://www.yr.no/en/content/2-4164138/meteogram.svg


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: new here

2024-08-21 Thread dn via Python-list

On 21/08/24 10:26, Daniel via Python-list wrote:

Hi folks -

New here. I've perused some posts and haven't seen a posting FAQ for
this NG. I'm learning python right now to realize some hobby goals I
have regarding some smolnet services. What are the NG standards on
pasting code in messages? Do yall prefer I post a pastebin link if it's
over a certain number of lines? I know this isn't IRC - just asking.



Welcome Daniel!

Despite some seeming to think of sending you elsewhere, there are a 
number of people 'here' who regularly volunteer their time to help others.


As with any interaction, the quality of information in the question 
directly impacts what can be offered in-response.


More of us can help with (pure) Python questions. Moving into 
specialised areas may reduce the number who feel competent to answer.


We'll value any contribution you may be able to offer, and will look 
forward to hearing of the projects you attempt...


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: bring back nntp library to python3

2024-08-14 Thread dn via Python-list

On 15/08/24 10:56, Alan Gauld via Python-list wrote:

On 14/08/2024 23:32, Left Right via Python-list wrote:
Lots of people care but the ability to influence these
decisions seems to have been removed far from the
general python user community. Python has moved from
the BDFL/Bazaar to the Committee/Cathedral. Probably
an inevitable consequence of its current "popularity".



Perhaps in the ?good, old, days when Python was the small, scrappy 
language a strong community formed because there was a strong sense of 
"us" - as in, "us against the world". This atmosphere generates 
"cohesion" within the group.


Does it (still) exist today? Where/when?


Python is a victim of its own success. It is now used in so many 
different fields within computing it is not possible for one person to 
say "I use it all". Thus, when someone says (s)he is a "Python 
Programmer" what is meant is most-likely one of web/front-end work, 
back-end/server/networking, data science, machine learning, etc.


As a PUG-Leader, this a daunting part of trying to generate and keep 
'community'. 'Data science people' won't attend 'web' meetings 
(by-and-large), and vice-versa - indeed some even feel the 'right' to 
moan that some other area of Python happens to be the topic for the next 
meeting.


The converse view (which is seldom well-taken if offered as a riposte to 
such complaints) is that if folk volunteer in some way, their efforts 
will (most likely) be embraced with gratitude - but how many do make 
such offers/participate in a practical fashion!


Whither community? Cohesion?


Thus, a grave difficulty for leaders who are unable to see these sorts 
of concerns - and act accordingly. A shift that should have occurred 
within steering groups as Python grew in popularity, was to add 
applications-expertise to the central group of Core Maintainers. 
However, unless there is trust and respect between members, one may be 
(too) quick to reject comments and ideas from 'another'.


Perhaps Python's state-of-democracy is heavily influenced by 
nation-state politics, where the desire for division seems to be 
overwhelming ideas of community/society? How does such benefit community 
- those represented?



Growth and size will inevitably require adaption. Almost inevitably it 
brings 'structure'. Whereas some do care (per @Alan's point), the 
average Python-programmer probably doesn't understand the current 
structures, and might even eschew such/reject their need.


How does this fit with "community"? What is personal-responsibility? 
What channels should folk be using? Are members of the community feeling 
'heard'?



If a committee perceives themselves besieged, the tendency is to look 
inwards and become determinedly-defensive - which, in cases like this, 
is likely the exact opposite of what the decision's opponents desire!


How should a 'community' handle such? How should decisions be made, and 
then communicated in such a way as to promote and build community, even 
though some members may be disappointed?



Recently there was an election for PSF members. Did 'everyone' participate?

What decision-making processes are usable in the face of such large 
numbers - and how seriously are/would they be taken by 'the average 
Python user'?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Help needed - - running into issues with python and its tools

2024-08-03 Thread dn via Python-list

On 4/08/24 09:34, o1bigtenor via Python-list wrote:

On Sat, Aug 3, 2024 at 4:06 PM dn via Python-list 
wrote:


On 4/08/24 08:17, o1bigtenor via Python-list wrote:

Greetings

Looking at ESP8266 and wanting to program it using micropython (really
don't want to have to learn C++ (not enough hours in the day as it

is!!)).


One of the tools I need to be able to use is esptools - -  well in the
devuan world you need to run that on either Devaun 3 or 5 - - - its just
not available on devuan 4.

Tried installing all the tools I need using downloads and .deb installs

but

then I need to have python3.12 and that's also not part of Devuan4.

Not versed enough to set up a good venv (if that's possible) so that I
could work in that specific venv and have my cake (and get to eat it too
(grin!).

Suggestions - - - ideas - - - please?


Sorry if this offends, but this is a list of short-cuts and reasons why
they don't work (immediately).


Have just come from a discussion about 'how to start a project'. Amongst
the questions to ask are: "what resources do we have (or can add) to
achieve?".



Fair question details interleaved - - -



In this case, if Python-skill is a "personnel-resource" (and C++ a
"constraint"), will question the ESP over Raspberry Pi (say)?



Well - - - RPi world technical specs is usable from -20 to 60 C (iirc on
the top number)
and for my project I absolutely need to have usability to at least -40 - -
could possibly do a bit less but -35 C is a hard requirement so the RPi
and Pico (which I would like to use) is out but ESP8266 runs in that -40 to
65 C
range.


Interesting, but creates a mis-match of tools - battles for you to fight...



Why talking of Python 3.12 when the solution involves MicroPython?



Because one uses psytool on one computer to transfer a program to the
MicroPython system.  In fact there are a set of tools that need Python3.12
to be able to do this and therefore the question.




Perhaps need to take a step back and look at 'options' - relate needs to
resources, and evaluate the impact of each decision on later ones - as
well as against your personal skills (modify objectives to limits, or
accept that some learning/training will be necessary as pre-requisite to
(being able to) attack the project).

I have been investigating using a venv but am not finding clear directions

so
that I could set up Python3.12 inside (along with the other needed tools).
The
more I'm looking the less useful most of the information I'm finding is
becoming.
Therefore I thought I would go to the python gurus for information - - -
which I
have.

So please - - - how do I set up a venv so that I can install and run python
3.12
(and other needed programs related to 3.12) inside?


If you mean venv itself, which "directions" have you reviewed?
This one (https://python.land/virtual-environments/virtualenv) seems 
very straight-forward and shows "What's inside a venv?" to include 
python.exe. Given that venv is more-or-less the official/traditional 
solution, what are you doing differently - perhaps the question is 
lacking detail.

(see also @Cameron's take)

Personally, I'm using Poetry (https://python-poetry.org) which seemed 
just as easy to pick-up; plus pyenv to maintain multiple versions of 
Python on one machine.


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Help needed - - running into issues with python and its tools

2024-08-03 Thread dn via Python-list

On 4/08/24 08:17, o1bigtenor via Python-list wrote:

Greetings

Looking at ESP8266 and wanting to program it using micropython (really
don't want to have to learn C++ (not enough hours in the day as it is!!)).

One of the tools I need to be able to use is esptools - -  well in the
devuan world you need to run that on either Devaun 3 or 5 - - - its just
not available on devuan 4.

Tried installing all the tools I need using downloads and .deb installs but
then I need to have python3.12 and that's also not part of Devuan4.

Not versed enough to set up a good venv (if that's possible) so that I
could work in that specific venv and have my cake (and get to eat it too
(grin!).

Suggestions - - - ideas - - - please?


Sorry if this offends, but this is a list of short-cuts and reasons why 
they don't work (immediately).



Have just come from a discussion about 'how to start a project'. Amongst 
the questions to ask are: "what resources do we have (or can add) to 
achieve?".


In this case, if Python-skill is a "personnel-resource" (and C++ a 
"constraint"), will question the ESP over Raspberry Pi (say)?


Why talking of Python 3.12 when the solution involves MicroPython?


Perhaps need to take a step back and look at 'options' - relate needs to 
resources, and evaluate the impact of each decision on later ones - as 
well as against your personal skills (modify objectives to limits, or 
accept that some learning/training will be necessary as pre-requisite to 
(being able to) attack the project).


--
Regards =dn

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Predicting an object over an pretrained model is not working

2024-07-30 Thread dn via Python-list

On 31/07/24 06:18, marc nicole via Python-list wrote:

Hello all,

I want to predict an object by given as input an image and want to have my
model be able to predict the label. I have trained a model using tensorflow
based on annotated database where the target object to predict was added to
the pretrained model. the code I am using is the following where I set the
target object image as input and want to have the prediction output:


...



WHile I expect only the dict to contain the small_ball key



How's that is possible? where's the prediction output?How to fix the code?



To save us lots of reading and study to be able to help you, please advise:

1 what are the meanings of all these numbers?


'sheep': [[233.0, 92.0, 448.0, -103.0,

5.3531270027160645], [167.0, 509.0, 209.0, 101.0, 4.947688579559326],
[0.0, 0.0, 448.0, 431.0, 3.393721580505371]]


2 (assuming it hasn't) why the dict has not been sorted into a 
meaningful order


3 how can one tell that the image is more likely to be a sheep than a train?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Best use of "open" context manager

2024-07-06 Thread dn via Python-list

On 6/07/24 22:49, Rob Cliffe via Python-list wrote:

Consider this scenario (which I ran into in real life):
     I want to open a text file and do a lot of processing on the lines 
of that file.
     If the file does not exist I want to take appropriate action, e.g. 
print an error message and abort the program.

I might write it like this:

try:
     with open(FileName) as f:
         for ln in f:
             print("I do a lot of processing here")
             # Many lines of code here .
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()

but this violates the principle that a "try" suite should be kept small, 
so that only targeted exceptions are trapped,


Yes!


not to mention that having "try" and "except" far apart decreases 
readability.


Uh-oh!

- and there's a bit of a hang-over for old-timers who had to take care 
of file-locking within the application - we try to minimise 'time' 
between opening a file and closing it (etc)!


As it seems the file is opened to read. Less relevant in this case, but 
habits and styles of coding matter...




Or I might write it like this:

try:
     f = open(FileName) as f:
     FileLines = f.readlines()
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()
# I forgot to put "f.close()" here -:)
for ln in File Lines:
         print("I do a lot of processing here")
         # Many lines of code here .

but this loses the benefits of using "open" as a context manager,
and would also be unacceptable if the file was too large to read into 
memory.


So, now there are two concerns:
1 FileNotFoundError, and
2 gradual processing to avoid memory-full

- added to remembering to close the file.



Really I would like to write something like

try:
     with open(FileName) as f:
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()
else: # or "finally:"
         for ln in f:
             print("I do a lot of processing here")
             # Many lines of code here .

but this of course does not work because by the time we get to "for ln 
in f:" the file has been closed so we get

ValueError: I/O operation on closed file

I could modify the last attempt to open the file twice, which would 
work, but seems like a kludge (subject to race condition, inefficient).


Is there a better / more Pythonic solution?


Idea 1: invert the exception handling and the context-manager by writing 
a custom context-manager class which handles FileNotFoundError 
internally. Thus, calling-code becomes:


with...
for...
processing

Idea 2: incorporate idea of encapsulating "processing" into a 
(well-named) function to shorten the number of lines-of-code inside the 
with-suite.


Idea 3: consider using a generator to 'produce' lines of data 
one-at-a-time. Remember that whilst context-managers and generators are 
distinct concepts within Python, they are quite similar in many ways. 
So, a custom generator could work like a context-manager or 'wrap' a 
context-manager per Idea 1.


Building a custom-class (Idea 1 or Idea 3) enables the components to be 
kept together, per the ideal. It keeps the try-except components close 
and easy to relate. It is Pythonic (in the OOP style).


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Anonymous email users

2024-06-24 Thread dn via Python-list

On 25/06/24 05:17, Thomas Passin via Python-list wrote:

On 6/24/2024 5:51 AM, Barry Scott via Python-list wrote:



On 23 Jun 2024, at 06:58, Sebastian Wells via Python-list 
 wrote:


The spammers won the spam wars, so even if you have someone's real
e-mail address, that's no guarantee that you can contact them. You
certainly wouldn't be able to contact me at my real e-mail address,
unless you also had my phone number, so you could call me and tell
me that you sent me an e-mail, and what the subject line was so I
can find it. I don't even open my e-mail inbox unless there's a
specific message I'm expecting to find there right now.


My email address is well known and yes I get spam emails.

I use the wonderful python based spambayes software to detect spam and
file into a Junk folder. It works for 99.9% of the emails I get.


I use the Thunderbird mail client and I just use its built in spam 
detector.  I don't know how it works but it's pretty darn good.  Very 
few false positives or false negatives.  And it learns each time I 
classify a message as "Junk", in case it missed one.


I am subscribed to a lot of mailing lists. I just checked and I am 
getting ~3,200

emails a month of which less than 200 are spam.

A few years ago the spam count was greater than a 1,000 a month.

I have been using spambayes for a very long time, 20 years I guess at 
this

point and bayesian categorisation has stood the test of time for me.

For me the spammers have not won, I have the tech to keep ahead of them.


Aside from the attractions of the new, and the 'shiny', what 
email-antagonists didn't anticipate, was that as fast as they moved to 
non-email messaging, the spammers, advertisers, and malcontents would 
simply do the same. Thus, a variation on whack-a-mole, as folk move from 
platform to platform trying to stay-ahead and find an illusion of 
safety. Quite how one out-runs human-nature is an issue 
philosophised-over by the (Ancient) Greeks (and was no-doubt old even-then).


Paradoxically, applying for an account elsewhere usually involves 
providing an email address. Even backing-up a cell-phone (communication 
tool) to the cloud requires an email address(!!!)


Most of the non-email platforms are provided by organisations who have 
'other uses' for your personal-data (and not forgetting GMail and MSFT's 
email services).


Python mailing-lists are covered by the Code of Conduct and monitored by 
ListAdmins. Thus, there are controls which limit the impact which 
advertisers and others with non-pythonic aims might otherwise exert!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Anonymous email users

2024-06-17 Thread dn via Python-list

On 18/06/24 05:29, Roel Schroeven via Python-list wrote:

AVI GROSS via Python-list schreef op 17/06/2024 om 17:03:
I simply am thinking that people who do not allow me to easily reply 
to them

directly, should be ignored by me and not get my cooperation that way.
FWIW, personally I (mostly) don't see the point of replying to people 
personally. To me a public mailing list is much like any public forum, 
where my expectation is that conversations happen in public. To me it 
always feels weird when I get a personal reply when I make a public post 
in a mailing list. I mostly ignore those, unless there's really 
something in it that's best kept out of the public. Sometimes people 
write long mails with wandering thoughts only loosely related to the 
topic at hand directly to me instead of to the whole list. My take is: 
if it's not on-topic enough for the list, it's not on-topic enough for 
me either. Not that it bothers me *that* much; I just ignore those. It's 
very well possible that's just me, and that other people have different 
expectations.


+1

The "public" part is not to embarrass posters, but recognition that 
there are likely other people 'out there' (or arriving in-future if they 
care to read the archives) experiencing a similar problem. (hence need 
for descriptive Subject lines - isn't the most difficult task in 
programming 'choosing names'?)


Yes, like @Avi, I have been known to contact folk directly. However, 
such for personal purposes - as distinct from the list, and possibly 
subjects OT for the list.


When contacted by others off-list, I play it by ear - ignore, personal, 
or post response on-list. (some lists/email-clients do seem to prefer 
personal replies, even when incoming message is from a list - so easy 
accident.)


The Delete-key is your friend!

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Anonymous email users

2024-06-14 Thread dn via Python-list

On 15/06/24 10:00, AVI GROSS via Python-list wrote:

I notice that in some recent discussions, we have users who cannot be
replied to directly as their email addresses are not valid ones, and I
believe on purpose. Examples in the thread I was going to reply to are:

...

It's an interesting conundrum. There are good reasons and nefarious, for 
such behavior.


Some have questioned my behavior in similar regard - asking why I use 
initials (also used IRL). It is because my first name "David" is/was 
very popular. At a meeting this week there were three of us. Thus, 
"David", "Dave", and "dn" was necessary to distinguish between us.



These mailing-lists all run under the Python Code of Conduct.

This also effects a conundrum. Firstly, that someone abusing others (for 
example) shall be held responsible. Secondly, that in order to hold 
someone responsible, he/she/... must be identifiable.



Personal opinion: if someone is asked a 
question/clarification/sample-code, particularly as a response to their 
own OP, and does not answer; this is at the least rude, and thus 
disrespectful, or at worst grounds for not bothering with them again - 
hardly a 'community' attitude!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: From JoyceUlysses.txt -- words occurring exactly once

2024-06-04 Thread dn via Python-list

On 31/05/24 14:26, HenHanna via Python-list wrote:

On 5/30/2024 2:18 PM, dn wrote:

On 31/05/24 08:03, HenHanna via Python-list wrote:


Given a text file of a novel (JoyceUlysses.txt) ...

could someone give me a pretty fast (and simple) Python program 
that'd give me a list of all words occurring exactly once?


   -- Also, a list of words occurring once, twice or 3 times



re: hyphenated words    (you can treat it anyway you like)

    but ideally, i'd treat  [editor-in-chief]
    [go-ahead]  [pen-knife]
    [know-how]  [far-fetched] ...
    as one unit.





Split into words - defined as you will.
Use Counter.

Show some (of your) code and we'll be happy to critique...



hard to decide what to do with hyphens
    and apostrophes
  (I'd,  he's,  can't, haven't,  A's  and  B's)


2-step-Process

   1. make a file listing all words (one word per line)

   2.  then, doing the counting.  using
   from collections import Counter



Apologies for lateness - only just able to come back to this.

This issue is not Python, and is not solved by code!

If you/your teacher can't define a "word", the code, any code, will 
almost-certainly be wrong!



One of the interesting aspects of our work is that we can write all 
manner of tests to try to ensure that the code is correct: unit tests, 
integration tests, system tests, acceptance tests, eye-tests, ...


However, there is no such thing as a test (or proof) that statements of 
requirements are complete or correct!

(nor for any other previous stages of the full project life-cycle)

As coders we need to learn to require clear specifications and not 
attempt to read-between-the-lines, use our initiative, or otherwise 'not 
bother the ...'. When there is ambiguity, we should go back to the 
user/client/boss and seek clarification. They are the 
domain/subject-matter experts...


I'm reminded of a cartoon, possibly from some IBM source, first seen in 
black-and-white but here in living-color: 
https://www.monolithic.org/blogs/presidents-sphere/what-the-customer-really-wants


That has been the sad history of programming and dev.projects - wherein 
we are blamed for every short-coming, because no-one else understands 
the nuances of development projects.


If we don't insist on clarity, are we our own worst enemy?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: From JoyceUlysses.txt -- words occurring exactly once

2024-05-30 Thread dn via Python-list

On 31/05/24 08:03, HenHanna via Python-list wrote:


Given a text file of a novel (JoyceUlysses.txt) ...

could someone give me a pretty fast (and simple) Python program that'd 
give me a list of all words occurring exactly once?


   -- Also, a list of words occurring once, twice or 3 times



re: hyphenated words    (you can treat it anyway you like)

    but ideally, i'd treat  [editor-in-chief]
    [go-ahead]  [pen-knife]
    [know-how]  [far-fetched] ...
    as one unit.



Did you mention the pay-rate for this work?


Split into words - defined as you will.
Use Counter.

Show some (of your) code and we'll be happy to critique...
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: SOLVED! Re: Weird Stuff (Markdown, syntax highlighting and Python)

2024-05-29 Thread dn via Python-list

On 29/05/24 06:49, Gilmeh Serda via Python-list wrote:


Solved by using a different method.



Hedonist for hire... no job too easy!


This combination of sig-file and content seems sadly ironic.


How about CONTRIBUTING to the community by explaining 'the solution' to 
people who may find a similar problem - in the similar manner to the 
various members who have helped YOU, voluntarily (and despite the 
paucity of source-information and response)?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Weird Stuff (Markdown, syntax highlighting and Python)

2024-05-27 Thread dn via Python-list
With reference to another reply here, the "Weird stuff" came from 
reading the question, finding it unclear, and only later realising that 
whereas most people write Markdown-formatted documents for later 
processing, or perhaps docstrings in Markdown-format for collection by 
documentation systems; here, the objective appears to be using Python to 
generate Markdown.


How much have you used Markdown to any serious degree, before attempting 
this feat?



On 26/05/24 18:28, Gilmeh Serda via Python-list wrote:

The web claims (I think on all pages I've read about Markdown and Python)
that this code should work, with some very minor variants on the topic:


There are so many "variants", the problem is not "minor"!

Markdown users learn to use their tool (again, see @Grant's question) 
and work within the implementation of that "variant".


Like any other non-standardised tool, the users of some particular 
'version' often fail to realise that others using different versions may 
not enjoy the same experience. Plus-one for standardisation!



At the end of the message, the web.refs reveal use of a package which is 
based upon a variant of Markdown that is 20-years old(!), albeit with 
some updates to suit yet another variant. Neither variant-author famous 
for collaboration. The phrase YMMV springs to mind...



Some ten years ago, an effort was made to standardise Markup, and it 
ended-up being called CommonMark. Why is it not called "Standard 
Markdown" one might ask? Because the fellow who 'invented' Markdown 
objected. This very objection has likely led directly to your 
confusions, because the particular PyPi package is based upon that 
original definition...


Whereas, Markdown 3.6 is the most-recently updated Markdown search-hit 
on PyPi today, have you tried any of the others (which, ironically, may 
offer more recent and/or more standardised coverage)?



This has worked in all of the Markdown processors I have used or tried-out:

The (?reasonable) 'common-core', offers single back-ticks for code, 
triple back-ticks for a code-block, and the latter with or without a 
language specification which *usually* kicks-in syntax highlighting.




```python

import os

with open(os.path.join('/home/user/apath', 'somefile')) as f:
 print(f.read())
```

However, that is not the case. At least not for me (using Python 3.12.3).


It's not Python 3 that is the problem. It is the "Markdown 3.6" package!



If instead I type it:



I've not seen the hash-bang combination in-the-wild (but YMMV!)


 #!python
 
 import os
 
 with open(os.path.join('/home/user/apath', 'somefile')) as f:

 print(f.read())

As an indented block (four spaces) and a shebang, THEN it works. You even
get line numbers by default.


An indented-block is NOT necessarily the same as a code-block - just as 
"code" is not necessarily "Python".


Line numbers are great - although if a code snippet is extracted from 
the middle of some example code-file, the original line-numbers won't 
line-up with Markdown's...




N.b. if you don't know, you also need to generate a css file using
pygments to make this work.


That's not what the package's docs suggest: 
https://python-markdown.github.io/extensions/fenced_code_blocks/




Not until I started to read the markdown source code and its docs pages,
the coin dropped.

I'm posting this for other Markdown newbies that otherwise probably would
spend hours trying to make it work.


Speaking of Markdown. Does anybody out there have any idea how to turn on
table borders, adjust them (color/width/etc.) and such things? Currently I
have to add HTML to do so, which works, but isn't very nice. I'd hate to
spend an additional day or two, hunting for this info.


Again, heavily dependent upon the tool in-use. For example, most SSGs 
and doc-tools (which accept Markdown) have a .css or theming-system 
which enables 'decorations'.




References:
https://pypi.org/project/Markdown/
https://python-markdown.github.io/


Further reading:
https://en.wikipedia.org/wiki/Markdown
https://commonmark.org
https://pypi.org/search/?q=markdown

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Cprod -- (writing this: itertools.product([0, 1], repeat=N )

2024-05-21 Thread dn via Python-list

On 22/05/24 07:14, HenHanna via Python-list wrote:


How can i write this function Cprod (Cartesian Product) simply?

     (writing this out: itertools.product([0, 1], repeat=N )

The value can be a list or a Tuple.

     cprod([0, 1], 1) => ((0) (1))

     cprod([0, 1], 2) => ((0,0) (0,1) (1,0) (1,1))



This works:

    def cprod(x, c):
     if c==1: return [[i] for i in x]
     Sub= cprod(x, c-1)
     return [i  for F in x   for i in [[F]+R for R in Sub]]


-- Is there another way to write [F]+R ???

    Other ways to improve it?


https://python.readthedocs.io/en/stable/library/itertools.html#itertools.product

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Data Ethics (Virtual) Meeting

2024-04-10 Thread dn via Python-list

Virtual meeting, Wed 17 April, 1800 for 1830 (NZST, ie 0630 UTC)


Data Ethics

Emma McDonald is the Director of the Interim Centre for Data Ethics and 
Innovation at Stats NZ (New Zealand Government Department of Statistics)


Emma will talk about why Stats NZ is establishing a Centre for Data 
Ethics and Innovation, and why it needs to be set up as a network that 
draws on and leverages knowledge and expertise across relevant work 
programmes and people across agencies. As an initiative, the Centre is 
there to help agencies develop and maintain secure and trusted data 
environments. A large part of this is drawing on a diverse network of 
people who can support the with sharing the importance of data ethics 
being a critical component of data driven technologies.


Will be of-interest to Quants, Data Science, and Machine Learning folk; 
as well as those of us with wider interest in what should/not happen 
with personal, public, and corporate data...


She will be wanting to hear what folk have to say, and is interested to 
recruit competent individuals for hui*, consultations, and the like.


WebRef: 
https://data.govt.nz/leadership/the-interim-centre-for-data-ethics-and-innovation/ 
from which you can access their Work Programme and Guidance developed 
to-date.



Please RSVP at https://www.meetup.com/nzpug-auckland/events/299764076/


* hui is the Te Reo Maori word for meeting or conference
(Te Reo is one of New Zealand's official languages)

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to Add ANSI Color to User Response

2024-04-10 Thread dn via Python-list

On 11/04/24 06:50, WordWeaver Evangelist via Python-list wrote:

I have a simple question. I use the following textPrompt in some of my Jython 
modules:
  '\nYour choice is? (A B C D E): ', maxChars=1, autoAccept=False, 
forceUppercase=True)
Is there a way to add an ANSI color code to the end where the conditions are, 
so that the color of the user’s input is of a color of my choosing, instead of 
just white?
Thank you very much in advance.
Kind regards,
Bill Kochman


Haven't tried using any of theses techniques, but may define input() 
color, as well as print():-


How to print colored terminal text in Python
MAR 06, 2024
...
https://byby.dev/py-print-colored-terminal-text

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Multiplication

2024-04-01 Thread dn via Python-list
The April Fools joke was on those of us who never received/have yet to 
receive @Stefan's OP.




On 2/04/24 08:02, Avi Gross via Python-list wrote:

Is this a April 1 post for fools.

Multiplication with an asterisk symbol is built into python.

The same symbol used in other contexts has other contexts has an assortment
of largely unrelated meanings such as meaning everything when used to
import.


On Mon, Apr 1, 2024, 1:27 PM Piergiorgio Sartor via Python-list <
python-list@python.org> wrote:


On 01/04/2024 10.40, Stefan Ram wrote:

  Q: How can I multiply two variables in Python? I tried:

a = 2
b = 3
print( ab )

  but it did not work.

  A: No, this cannot work. To multiply, you need the multiplication
  operator. You can import the multiplication operator from "math":

  Code example:

from math import *

a = 2
b = 3
print( a * b )


I guess the operator "*" can be imported from any module... :-)

bye,

--

piergiorgio

--
https://mail.python.org/mailman/listinfo/python-list



--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: MTG: Introductions to PyQt and DataClasses

2024-03-17 Thread dn via Python-list

On 18/03/24 10:02, Jim Schwartz wrote:

Actually, I have a sleep disorder that requires me to keep a constant sleep 
schedule. Thats why I asked.


At a weekend meeting, discussion swirled around topics such as the best 
way to learn/work, how much work we should attempt in one sitting, 
could/should I 'do more', and similar.


One of the valuable observations is that most of us would benefit by 
improving our sleep-schedule and ensuring we do sleep for sufficient 
time (probably longer than current habit).


--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Configuring an object via a dictionary

2024-03-17 Thread dn via Python-list

On 18/03/24 04:11, Peter J. Holzer via Python-list wrote:

On 2024-03-17 17:15:32 +1300, dn via Python-list wrote:

On 17/03/24 12:06, Peter J. Holzer via Python-list wrote:

On 2024-03-16 08:15:19 +, Barry via Python-list wrote:

On 15 Mar 2024, at 19:51, Thomas Passin via Python-list 
 wrote:
I've always like writing using the "or" form and have never gotten bit


I, on the other hand, had to fix a production problem that using “or” 
introducted.
I avoid this idiom because it fails on falsy values.


Perl has a // operator (pronounced "err"), which works like || (or),
except that it tests whether the left side is defined (not None in
Python terms) instead of truthy. This still isn't bulletproof but I've
found it very handy.



So, if starting from:

 def method( self, name=None, ):

  rather than:

 self.name = name if name else default_value

ie

 self.name = name if name is True else default_value


These two lines don't have the same meaning (for the reason you outlined
below). The second line is also not very useful.




the more precise:

 self.name = name if name is not None or default_value

or:

 self.name = default_value if name is None or name


Those are syntax errors. I think you meant to write "else" instead of
"or".

Yes, exactly. That's the semantic of Perl's // operator.

JavaScript has a ?? operator with similar semantics (slightly
complicated by the fact that JavaScript has two "nullish" values).



Thanks Peter!
(yes, sad consequences of suffering a neighbor's party-til-midnight 
followed by an 0530 meeting-start - children: don't code exhausted!)



Herewith, an illustration of how the corrected version of the above 
works - and how (in what seem unusual cases) it avoids any truthy/falsy 
confusion, as raised earlier in this thread:


>>> default_value = "default"
>>> name = "Fred Flintstone"
>>> name if name is not None else default_value
'Fred Flintstone'

>>> name = None
>>> name if name is not None else default_value
'default'
>>> name = False
>>> name if name is not None else default_value
False
>>> name = 1
>>> name if name is not None else default_value
1
>>> name = 0
>>> name if name is not None else default_value
0


Personally: I find the above coding more logical, because our primary 
interest is on 'the happy case', ie where the value has been assigned 
(to "name"); and the default_value is only applied as a "guard".



On the other hand, I dislike the not-condition because it forces me to 
think (and maybe dust-off DeMorgan). Accordingly:


>>> name = "Fred Flintstone"
>>> default_value if name is None else name
'Fred Flintstone'
>>> name = None
>>> default_value if name is None else name
'default'
>>> name = False
>>> default_value if name is None else name
False
...


YMMV!
NB your corporate Style Guide may prefer 'the happy path'...

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: MTG: Introductions to PyQt and DataClasses

2024-03-17 Thread dn via Python-list

On 17/03/24 23:40, Jim Schwartz wrote:

Will it be recorded?


Better than that (assumption) "coming soon" - please join-up or keep an 
eye on PySprings' Meetup ANNs: https://www.meetup.com/pysprings/




On Mar 17, 2024, at 1:47 AM, dn via Python-list  wrote:

The Auckland Branch of NZPUG meets this Wednesday, 20 March at 1830 NZDT (0530 
UTC, midnight-ish Tue/Wed in American time-zones), for a virtual meeting.

Part 1: Learn the basics of PyQt with code examples.
Hannan Khan is currently consulting as a Data Scientist for the (US) National 
Oceanic and Atmospheric Administration. He holds a Bachelor's degree in 
Neuroscience as well as a Masters in Computer Science. As a keen member of the 
PySprings Users' Group (Colorado), his contribution is part of a collaboration 
between our two PUGs.

Part 2: Why use Dataclasses?
- will be the question asked, and answered, by yours truly. After surveying a 
number of groups, it seems most of us know that Dataclasses are available, but 
we don't use them - mostly because we haven't ascertained their place in our 
tool-box. By the end of this session you will, and will have good reason to use 
(or not) Dataclasses!

Everyone is welcome from every location and any time-zone. The NZPUG Code of 
Conduct applies. JetBrains have kindly donated a door-prize. Our BigBlueButton 
web-conferencing instance is best accessed using Chromium, Brave, Vivaldi, 
Safari, etc, (rather than Firefox - for now). A head-set will facilitate asking 
questions but text-chat will be available.

Please RSVP at https://www.meetup.com/nzpug-auckland/events/299764049/
See you there!
=dn, Branch Leader
--
https://mail.python.org/mailman/listinfo/python-list




--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


MTG: Introductions to PyQt and DataClasses

2024-03-16 Thread dn via Python-list
The Auckland Branch of NZPUG meets this Wednesday, 20 March at 1830 NZDT 
(0530 UTC, midnight-ish Tue/Wed in American time-zones), for a virtual 
meeting.


Part 1: Learn the basics of PyQt with code examples.
Hannan Khan is currently consulting as a Data Scientist for the (US) 
National Oceanic and Atmospheric Administration. He holds a Bachelor's 
degree in Neuroscience as well as a Masters in Computer Science. As a 
keen member of the PySprings Users' Group (Colorado), his contribution 
is part of a collaboration between our two PUGs.


Part 2: Why use Dataclasses?
- will be the question asked, and answered, by yours truly. After 
surveying a number of groups, it seems most of us know that Dataclasses 
are available, but we don't use them - mostly because we haven't 
ascertained their place in our tool-box. By the end of this session you 
will, and will have good reason to use (or not) Dataclasses!


Everyone is welcome from every location and any time-zone. The NZPUG 
Code of Conduct applies. JetBrains have kindly donated a door-prize. Our 
BigBlueButton web-conferencing instance is best accessed using Chromium, 
Brave, Vivaldi, Safari, etc, (rather than Firefox - for now). A head-set 
will facilitate asking questions but text-chat will be available.


Please RSVP at https://www.meetup.com/nzpug-auckland/events/299764049/
See you there!
=dn, Branch Leader
--
https://mail.python.org/mailman/listinfo/python-list


Re: Configuring an object via a dictionary

2024-03-16 Thread dn via Python-list



On 17/03/24 12:06, Peter J. Holzer via Python-list wrote:

On 2024-03-16 08:15:19 +, Barry via Python-list wrote:

On 15 Mar 2024, at 19:51, Thomas Passin via Python-list 
 wrote:
I've always like writing using the "or" form and have never gotten bit


I, on the other hand, had to fix a production problem that using “or” 
introducted.
I avoid this idiom because it fails on falsy values.


Perl has a // operator (pronounced "err"), which works like || (or),
except that it tests whether the left side is defined (not None in
Python terms) instead of truthy. This still isn't bulletproof but I've
found it very handy.



So, if starting from:

def method( self, name=None, ):

 rather than:

self.name = name if name else default_value

ie

self.name = name if name is True else default_value


the more precise:

self.name = name if name is not None or default_value

or:

self.name = default_value if name is None or name

because "is" checks for identity, whereas "==" and True-thy encompass a 
range of possible alternate values?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Configuring an object via a dictionary

2024-03-16 Thread dn via Python-list

On 16/03/24 21:15, Barry via Python-list wrote:




On 15 Mar 2024, at 19:51, Thomas Passin via Python-list 
 wrote:

I've always like writing using the "or" form and have never gotten bit


I, on the other hand, had to fix a production problem that using “or” 
introducted.
I avoid this idiom because it fails on falsy values.


As with any other facility, one has to understand ALL implications!

It must be one of those intensely-frustrating errors to track-down, 
which is then oh-so-simple to fix!


Are you able to list (real, if suitably anonymised) examples of where 
the truthy/falsy was inappropriate, please?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Configuring an object via a dictionary

2024-03-15 Thread dn via Python-list

On 15/03/24 22:30, Loris Bennett via Python-list wrote:

Hi,

I am initialising an object via the following:

 def __init__(self, config):

 self.connection = None

 self.source_name = config['source_name']
 self.server_host = config['server_host']
 self.server_port = config['server_port']
 self.user_base = config['user_base']
 self.user_identifier = config['user_identifier']
 self.group_base = config['group_base']
 self.group_identifier = config['group_identifier']
 self.owner_base = config['owner_base']

However, some entries in the configuration might be missing.  What is
the best way of dealing with this?


How do you define "missing"?

Thus, @Thomas' suggestion may/not apply. It is neat and easy.

I usually plump for:

self.source_name = config[ "source_name" ] or default_value

but @Grant's warning applies!
(which is why the pythonic way is to use (and test for) None as a 
definition of "missing" (see also impacts of using default values and 
mutable data-structures)



LBYL cf EAFP:
When setting-up an environment like this, elements are often set to a 
default-value, and then user-settings, command-line arguments, and the 
like, applied in a priority-order sequence, amend as-appropriate. In 
this way, such problems will never arise.


This is the better course 90% of the time.


Which raises the next question:

What is the impact if some attribute is "missing"? ie if the 'whatever' 
must be identified by source_name (for example), then there is little 
point in assigning any values to the new class. Considerations which 
apply *after* this question, the __init__(), are at least 
equally-important considerations (see below)!




I could of course simply test each element of the dictionary before
trying to use.  I could also just write

self.config = config

but then addressing the elements will add more clutter to the code.


By which you mean that such "clutter" should only appear in the 
__init__() - which is not such a bad idea (but see below).


OTOH it is often helpful to one's comprehension to be given a prompt as 
to the source of the data. Thus, in later processing *config[ 
"source_name" ] may add a small amount of extra information to the 
reader, over self.source_name.


* maybe prepended "self.", or not...


Am assuming that passing all eight elements as individual arguments is 
off-the-table, embodying far too many 'negatives' (see below).




However, with a view to asking forgiveness rather than
permission, is there some simple way just to assign the dictionary
elements which do in fact exist to self-variables?


Assuming config is a dict:

self.__dict__.update( config )

will work, but attracts similar criticism - if not "clutter" then an 
unnecessary view (and understanding) of the workings of classes 
under-the-hood.



Another question:
When these values are used, are they all used at the same time, and 
never again? It may only be worth 'breaking-out' and making attributes 
from those which are used in multiple situations within the class's 
methods. If, the other extreme, they are only (effectively) passed from 
the __init__() to some sort of open() method, then pass the 
data-structure as an whole and delegate/remove the "clutter" to there. 
In that scenario, such detail would *only* has meaning *and* purpose in 
the open() method and thus no point in cluttering-up the __init__() with 
detail that is only required elsewhere!




Or should I be doing this completely differently?


YMMV, but I prefer the idea of transferring the environment/config as a 
whole (as above).


If it were a class (cf the supposed dict) then "clutter" is reduced by 
eschewing brackets and quotation-marks, eg "config.source_name".



If those eight-elements are not the entirety of that data-structure, 
then consider creating an interface-class, which is extracted (or built 
that way) from some wider 'environment', and used to set-up access to 
data-source(s) or whatever. Again, this aids understanding in knowing 
where data has been created/gathered, and improves confidence when 
utilising it down-the-line.


The other principle in only providing the required (eight) items of 
data, is that the 'receiving-class' needs no understanding of the 
structure or workings of the 'sending-class' = separation of concerns, 
and each class has single purpose/reason to change.



A variation on that might be to use a method/function as the interface:

access = Access( config.access_data )

Thus, the config class (instance) will need an access_data method to 
collate the data-items. The complimentary code in this Access.__init__( 
self, config, ) might be something like:


(
self.source_name,
self.server_host,
self.server_port,
self.user_base,
self.user_identifier,
self.group_base,
self.group_identifi

Re: A Single Instance of an Object?

2024-03-11 Thread dn via Python-list

Good question Rambius!

On 12/03/24 09:53, Ivan "Rambius" Ivanov via Python-list wrote:

Hello,

I am refactoring some code and I would like to get rid of a global
variable. Here is the outline:

import subprocess

CACHE = {}


First thought: don't reinvent-the-wheel, use lru_cache 
(https://docs.python.org/3/library/functools.html)




The global cache variable made unit testing of the lookup(key) method
clumsy, because I have to clean it after each unit test. I refactored
it as:

class Lookup:
 def __init__(self):
 self.cache = {}



Change "cache" to be a class-attribute (it is currently an instance.

Then, code AFTER the definition of Lookup can refer to Lookup.cache, 
regardless of instantiation, and code within Lookup can refer to 
self.cache as-is...



--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread dn via Python-list

On 7/03/24 05:28, Jacob Kruger via Python-list wrote:
...
So, yes, know this comes across like some form of a scam/joke, or 
list-garbage, since it doesn't make any sense to me at all, but still 
just wondering if missing something, or should I shift over to 3.12 to 
see if if works differently, or just try reinstalling 3.11 from scratch, 
or should I retry the above in something like the VS code console, or a 
different python console, etc.?
Some of the facts, such as HOW the code was being executed were missing 
(see earlier request for a cut-down scenario, AND reports from others 
saying 'but it works for me').


The idea of importing a module into the REPL and then (repeatedly) 
manually entering the code to set-up and execute is unusual (surely type 
such into a script (once), and run that (repeatedly). As you say, most 
of us would be working from an IDE and hitting 'Run'. Am wondering why 
you weren't - but it's not important.


That said, the REPL is the perfect place to learn, experiment, and 
prototype - particularly when compared with the facilities of other 
language's eco-systems. The entirety of the on-line Tutorial cannot be 
wrong! (although, after a quick review, I've failed to see where the 
Tutorial mentions the usual development mode, apart from two very brief 
asides (the most useful is almost at the very end(?)) - but then (as 
they say) the objective is to show the language!


The lesson-learned is that there are different 'environments' and 
different ways of building the environment in which the code will run. 
That's a valuable lesson, and full of subtlety!


Glad to see that comparing id()s was useful - for diagnosis but not 
solution. Other tools might include the locals() and globals() 
functions. You may also have detected that many of us try to avoid 
globals and the implicit assumptions about the behavior of mutable 
collections (eg lists) when treated as 'global'. Then there are 
"closures", the "LEGB" rule, namespaces, scope, and ...


--
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-05 Thread dn via Python-list

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At the 
very least, we can experiment without having to expend amounts of time 
in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am completely 
confused, or missing something - was that, for example, when having 
pre-defined a variable, and then included it in the global statement 
inside a function, that function was still referring to a completely 
local instance, without manipulating outside variable object at all 
unless I first executed a form of referral to it, before then possibly 
assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I just 
run bare-bones test code inside the python interpreter, but consistently 
occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first line
inside the functions includes the following:
# code snippet
     global l_servers
# end code snippet

That should, in theory, mean that if I assign a value to that variable
inside one of the functions, it should reflect globally?

However, it seems like that, while inside those functions, it can be
assigned a new list of values, but if I then return to the scope outside

the functions, it has reverted back to being an empty list = []?


The issue seems to specifically (or not) occur when I make a call to one 
function, and, in the steps it's executing in one context, while it's 
not doing anything to the list directly, it's then making a call to the 
second function, which is then meant to repopulate the list with a brand 
new set of values.



Now, what almost seems to be occurring, is that while just manipulating 
the contents of a referenced variable is fine in this context, the 
moment I try to reassign it, that's where the issue is occurring .



Here are relevant excerpts from the file:-


# start code

# original assignation in main part of file

l_servers = []


# function wich is initially being executed

def interact():
     global l_servers
     # extra code inbetween choosing what to carry out

     # ...

     # end of other code

     bl_response, o_out = list_servers()

     if bl_response: # just make sure other function call was successful

     l_servers.clear() # first make reference to global variable

     for srv in o_out: l_servers.append(srv) # now re-populate items

     # end code snippet from inside interact function

# end of interact function

# end of code snippet


That other function being called from within, list_servers() was 
initially just trying to populate the values inside the global list 
variable itself, but was ending up in a similar fashion - reverting to 
initial empty value, but, the above now seems to work, as long as I 
first make reference to/manipulate/work with global variable instead of 
just trying to reassign it a brand new value/set of items?



So, am I missing something obvious, have I forgotten about something 
else - yes, know that if was working from within an embedded function, I 
might need/want to then use the nonlocal statement against that variable 
name, but, honestly, just not sure how this can be occurring, and, it's 
not just with this one list variable, etc.?



If I try simple test code from within the python interpreter, using 
different types of variables, this does also not seem to be the same all 
the time, but, don't think it can relate to an iterable like a list, or 
else, just in case, here is the code snippet with all the import 
statements from the top of that file, in case something could be 
overriding standard behaviour - not likely in this context, but, really 
not sure what's occurring:


# import code snippet

import requests, time
from requests.auth import HTTPBasicAuth
import psutil as psu
import pytz
import bcrypt
from copy import copy
from datetime import datetime, timedelta, timezone
from dateutil.parser import parse

# end of import snippet


Thanks if you have any ideas/thoughts on the matter


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."




--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-l

Re: Can one output something other than 'nan' for not a number values?

2024-02-19 Thread dn via Python-list

On 20/02/24 01:04, Chris Green via Python-list wrote:

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.


Concur with earlier advice (and assuming is only a consideration during 
output) - use if.


Alternately, encode appropriately during the data-capture phase.


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Can one output something other than 'nan' for not a number values?

2024-02-19 Thread dn via Python-list

On 20/02/24 05:58, Grant Edwards via Python-list wrote:

Here's a demonstration of how to hook custom code into the f-string
formatting engine. It's brilliantly depraved.

https://stackoverflow.com/questions/55876683/hook-into-the-builtin-python-f-string-format-machinery

 From the above:

 You can, but only if you write evil code that probably should
 never end up in production software. So let's get started!
 
 I'm not going to integrate it into your library, but I will show

 you how to hook into the behavior of f-strings. This is roughly
 how it'll work:
 
  1. Write a function that manipulates the bytecode instructions of

 code objects to replace FORMAT_VALUE instructions with calls
 to a hook function;
 
  2. Customize the import mechanism to make sure that the bytecode

 of every module and package (except standard library modules
 and site-packages) is modified with that function.

Final code is here:

https://github.com/mivdnber/formathack


Some of this (Expression components inside f-strings) newly available in 
v3.12 (PEP-701) - which can be used in production...


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Testing (sorry)

2024-02-18 Thread dn via Python-list

On 19/02/24 12:09, Grant Edwards via Python-list wrote:
...


But posts to the list still seemed to vanish into the ether while
emails from both accounts reached other destinations without delay,

During this process a number of posts from other users did appear in
the list archive and at at _one_ of the two e-mail addresses which I
had subscribed.

But no sign of any of my posts.

About 24 hours later, all of my posts (and the confirmation e-mails)
all showed up in a burst at the same time on two different unrelated
e-mail accounts.

I still have no clue what was going on...


Looking at the email-headers, there are sometimes considerable delays 
between messages submitted to the List-reflector, and their outward 
transmission (to me).


Interestingly, there's something strange about the queuing. Instead of 
FIFO it seems some messages arrive ahead of others, ie out-of-sequence.

(wonder if explained by submission via email or Usenet?)

I've noted long delays too. Perhaps (also) to do with time-of-day?

Always feel slightly embarrassed if 'repeat' an answer* that someone 
else had previously submitted, eg __new__ thread and @MRAB. However, if 
the reflector 'holds onto' the earlier message, then how should I/anyone 
know?


* yes, repetition improves learning, slightly different words may help 
comprehension; but doubt I can express anything better than the 
aforementioned does/did/can.


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Can one output something other than 'nan' for not a number values?

2024-02-18 Thread dn via Python-list

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, ...?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Using __new__

2024-02-17 Thread dn via Python-list

On 18/02/24 13:21, Jonathan Gossage wrote:
The problem is that if you are dealing with a library class, you may 
have times when the superclass is 'object' while at other times, with a 
different inheritance hierarchy, the superclass may need arguments. My 
thought is that the object class __new__ method should not choke on 
arguments, just ignore them.


All true.

So, what you're looking for is one mechanism to rule them all?

Not going to happen: for exactly the reasons you've stated. If you 
really want to get right 'down into the weeds' with a __new__() 
constructor, then you're well into customisation-territory.


I think it would be 'going nuts' but...
If it 'absolutely, positively, ...' then perhaps introspect the 
super-class and modify the call based-upon whether it is 'something' or 
"object"?
(in similar fashion to the singleton's if-statement attempting to make 
sure it is unique)


- perhaps someone knows a better/proper way to do this?

Suggested research: custom classes, ABCs, and meta-classes...

See also recent improvements to Python which have made it easier for 
sub-classes (and Descriptors - __set_name__() ) to identify 
who/how/where to 'phone home', in case (also) applicable...



When I talk about 'object', I am talking about the ultimate base class 
of any inheritance hierarchy.  have seen the class named 'object' called 
that.


Correct.

The earlier comment was that

class S( object ):

is 'tradition', and synonymous with:

class S:

(not disputing the concept of "object" as the base class)


Not correct.

Please see last paragraph from previous message:


On Sat, Feb 17, 2024 at 7:06 PM dn via Python-list 
mailto:python-list@python.org>> wrote:

...


PS please reply to the list - there may be others who can learn
from, or
contribute to, this conversation!

...

--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Using __new__

2024-02-17 Thread dn via Python-list

On 18/02/24 12:48, Jonathan Gossage wrote:
The problem that I am facing is that when the superclass is not 
'object', the __init__ method may well need arguments. I do not know how 
to determine if the superclass is 'object'. For what it is worth, any 
attempt to use this with different arguments should return the initial 
singleton and ignore further attempts to create a second instance.

1 "object"
don't understand. Perhaps give us a broader description of the problem? 
Remember also ABCs (Abstract Base Classes).


2 arguments
yes, must accommodate arguments in __new__() if some/same are needed in 
__init__() However, when using the default "object", the super() does 
not need, use, or want, any arguments to be passed.


3 singleton
don't think that is happening!


PS please reply to the list - there may be others who can learn from, or 
contribute to, this conversation!


--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Using __new__

2024-02-17 Thread dn via Python-list

On 18/02/24 11:35, Jonathan Gossage via Python-list wrote:

I am attempting to use the __new__ method in the following code:
class SingletonExample(object):

 _instance = None

 def __new__(cls, **kwargs):
 if cls._instance is None:
 cls._instance = super().__new__(cls, **kwargs)
 return cls._instance

 def __init__(self, **kwargs) -> None:
 our_attributes = ('h', 'x')
 if kwargs is not None:
 for k, v in kwargs.items():
 if k in our_attributes:
 setattr(self, k, v)

a = SingletonExample(h=1)

and I get the following result:

(PRV) jonathan@jfgdev:/PR$ python -m Library.Testing.test2
Traceback (most recent call last):
   File "", line 198, in _run_module_as_main
   File "", line 88, in _run_code
   File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 16, in

 a = SingletonExample(h=1)
 ^
   File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 6, in
__new__
 cls._instance = super().__new__(cls, **kwargs)
 ^^
TypeError: object.__new__() takes exactly one argument (the type to
instantiate)

I am quite puzzled as it looks as if this code will not work if the
super-class is 'object'. Any suggestions on how to proceed?


Don't be puzzled. Read the error-message.

Change the super-call to: cls._instance = super().__new__(cls)
and happiness will follow...


That said, mystifications - not sure if this meets the/your definition* 
of "singleton", because:


- it can be aliased, eg
a = SingletonExample(h=1)
b = SingletonExample(x=2)

- when it is, the effect is an accumulation of attributes and values
a = SingletonExample(h=1)
b = SingletonExample(h=2)
print( a.__dict__, b.__dict__, )

- it can be re-created with a different value, eg
a = SingletonExample(h=1)
a = SingletonExample(h=2)

- and can be 'regenerated':
a = SingletonExample(h=1)
a = SingletonExample(x=2)

- all failures are silent


* noting "Nowadays, the Singleton pattern has become so popular that 
people may call something a singleton even if it solves just one of the 
listed problems." (https://refactoring.guru/design-patterns/singleton)



YMMV!

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: test-ignore

2024-02-15 Thread dn via Python-list

On 16/02/24 13:29, Skip Montanaro via Python-list wrote:



Test post to see if my Newsgroup post program is working.


Aim your test messages at alt.test, please.



I agree that basic Usenet connectivity messages should go to alt.test. It's
not clear from the original post, but if the poster's aim was to see if
posts to comp.lang.python traverse the gateway and show up on this list,
then alt.test won't help.


Coincidentally (I hope), today have received a couple of poorly-executed 
spam/phishing messages purporting to be from this list or "Tutor".


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-02-04 Thread dn via Python-list

On 4/02/24 13:20, avi.e.gr...@gmail.com wrote:

Dave,

You and I have had some experience in teaching or tutoring others and I think 
it fair to say our motivation is closer to teaching someone how they can fish 
for themselves rather than just handing them a fully-cooked fish.


Which may push the debate 'up' a level, in that there are two pertinent 
Python Discussion Lists (amongst the many): Tutor which is expressly for 
learners (and tutors), and this one which is to discuss Python. 
Accordingly, one might suggest that people 'here' are looking for a 
direct answer - the fish (having tried to fish for themselves), but 
learners (seeking to learn to fish) should be asking elsewhere.


This would sort-out the type/level of questions that OPs may have. As 
well as indicating an appropriate approach to 'answers'.


However, there's no rule which says one has to ask in one place or the 
other (nor am I suggesting such, although...). Then again, might the 
lack of forethought evident in some questions and the forum-used, 
indicate a type of person who wouldn't investigate to see which is the 
best place for his/her enquiries anyway?


Tutor List: https://mail.python.org/mailman/listinfo/tutor
Lists Overview: https://mail.python.org/mailman/listinfo



My favorite kinds of questions, thus, include someone who explains what they 
are trying to do and shows some code along with indications of what it produced 
(including error messages) and what it should produce. Then the question should 
not be a request to just FIX THIS or WRITE IT FOR ME but asking if someone can 
show what they did wrong with some idea where it went wrong.

This may not be so common but it allows faster and easier help.


+1


...


I will end with a comment. I have heard of interview techniques for a job where 
they deliberately supply a problem in which the goal is not so much to be easy 
to solve in front of them in real time but to watch how the person looking for 
a job responds to the uncertainties and asks follow-up questions or verbalizes 
things like, if it is like this, I might use this technique but if you also 
need that then ...

So, I shudder to think what happens if someone being interviewed turns around 
and asks us and further confuses things with changes to make it harder to 
recognize they are asking for outside help. The answer expected may well be to 
NOT use say the older versions of PASCAL to do something but switch to 
something better suited (and for that matter available.)  I would not want to 
program the DES encryption/decryption method in Pascal again! And these days, 
it seems much better to just find a module or package that meets such needs.


As you know, I investigate Cognitive Psychology. Accordingly, such is 
interesting to me. In many cases, I'll interview for motivation, not 
just particular skills - but perhaps that's another can-of-worms.


How about "when is 1 + 1 not 2?". This is a bit of a mind-bender, but 
leads towards debugging ability* - what if your code was showing some 
unbelievable result like this?


The answer is (or rather, "could be") 10, ie we're looking at binary cf 
decimal, coding.


Do I hear some groans? Yes, fair-enough! There was absolutely no 
"context" to the question - whereas when coding/debugging we would 
expect to have some 'framing' of our thinking. At the same time, 'fixed 
mode thinking' will prevent many people from even considering such 
possibilities - whether as-asked or in a dev.env...



* In the ?good old days, career progression was thought to be: 
(mainframe) Computer Operator, to Computer Programmer, to Systems 
Analyst, etc. However, as I pointed-out (to an IBM 'big-wig' who took an 
instant dislike as a result) the valued skills of an Analyst are that 
(s)he can see 'patterns' - whereas the skills of debugging involve 
realising why an expected pattern doesn't work (as-expected).



Another analysis might be to decide if the job requires a 'lateral 
thinker' or a more single-minded approach. (us lateral thinkers tend to 
ask (loads of) questions, and thus can be quite 'annoying' individuals).


Then there is the main-stay of many job-adverts: "attention to detail" 
and the question of whether someone who can't [be bothered to] write an 
half-decent email-message (with spell-checker likely built-in) is going 
to be productive when communicating with a pedantic compiler?



Again, some people are suited to this business (or specific jobs 
within), and some (?many) are not - but many are (perhaps reluctantly) 
programming to get some other job done...


--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-02-03 Thread dn via Python-list
Every trainer, in any field, has to deal with these problems - all the 
time, and over-and-over.



On 4/02/24 06:58, Thomas Passin via Python-list wrote:
In my view this whole thread became murky and complicated because the OP 
did not write down the requirements for the program.  Requirements are 
needed to communicate with other people.  An individual may not need to 
actually write down the requirements - depending on their complexity - 
but they always exist even if only vaguely in a person's mind.  The 
requirements may include what tools or languages the person wants to use 
and why.


If you are asking for help, you need to communicate the requirements to 
the people you are asking for help from.


The OP may have thought the original post(s) contained enough of the 
requirements but as we know by now, they didn't.


There is another possible interpretation in such situations (not 
necessarily this one): that the person is fixated on a particular 
solution (and unable/unwilling to adjust his/her thinking to consider 
more widely).


Thus, the question is not: 'here's an entire problem, how can it be 
solved', but more: 'I have a solution, and want help to implement it 
(and only it) just-so'.



The latter is an interesting psychology:

1
an experienced person who is trying to translate from one tool to 
another (Python), but discovers that a word-for-word solution is 
difficult because of the artificial-constraints they've placed on the 
situation.


2
a beginner who doesn't know what (s)he doesn't know and comes-up with an 
idea, but fails to appreciate that there is likely more than one path to 
the goal.



The person asking for help may not realize they don't know enough to 
write down all the requirements; an effort to do so may bring that lack 
to visibility.


In the case of 'Beginners' this should probably be taken-as-read!

Which is why we will always find ourselves asking questions or 'please 
give more information'...



However, there are other reasons, eg corporate concerns or personality; 
why people don't want to give more information. The former is reasonable 
(have suffered from same myself). The latter may reveal that the person 
is 'difficult to deal with'...



Mailing lists like these have a drawback that it's hard to impossible 
for someone not involved in a thread to learn anything general from it. 
We can write over and over again to please state clearly what you want 
to do and where the sticking points are, but newcomers post new 
questions without ever reading these pleas.  Then good-hearted people 
who want to be helpful end up spending a lot of time trying to guess 
what is actually being asked for, and maybe never find out with enough 
clarity.  Others take a guess and then spend time working up a solution 
that may or may not be on target.


So please! before posting a request for help, write down the 
requirements as best you can figure them out, and then make sure that 
they are expressed such that the readers can understand.


Unfortunately, if the person doesn't understand the problem (leave-aside 
any ideas of solution), then (s)he will not be able to clearly 
communicate same to us, in any way, shape, or form...


Which brings one to the question: if a person cannot express the problem 
clearly and completely, is (s)he suited to development work? If the 
problem is not understood, could 'the solution' ever be more than an 
exercise in hope?

(prototyping and experimentation aside)


Yes, it is frustrating to invest time and effort in helping someone, 
only for same to disappear 'into a black hole'. The lack of response 
seems to indicate a lack of respect or appreciation. Is this perhaps 
part of today's "consumer" life-style, where so few are contributors or 
creators?



On the other side of that coin: do the people who make assumptions and 
(kindly) blaze-ahead with 'a solution', actually help the conversation? 
If the assumptions are correct, yes! What if they are not?



...and don't get me started on folk who want us to do their 
training-assignments or build some application, for them!



As a slight aside: on one training-course DiscussionList/BulletinBoard 
set-up, if a trainee asked a question without a descriptive 
title/SubjectLine, eg "Python not working" or "Urgent: please help"; I 
asked them to re-post with a title that would help others in a similar 
situation find the topic - and closed the original thread.


Some found it "brutal" - probably skewing towards those who felt 
"Urgent" because they'd left things too close to deadline. Others joined 
the (later) thread because they could identify the topic and realise 
their interest in learning or contributing to the conversation...



Time pressures lead to a multitude of evils!


There's a quotation that goes something like "the poor will be with your 
always"?

(?possibly Biblical)

Whether we (here) are talking about 'poor' manners, 'poor' 
understanding, 'poor' communication skills, 'poor' P

MTG: pytest (NZPUG, Auckland, VacExcHndlrs)

2024-01-31 Thread dn via Python-list
Wed 7 Feb (evening NZDT) will be the last virtual gathering in the 
current Vacation Exception Handlers (VacExcHndlrs) series 
(https://danceswithmice.info/Python/2024/VacExcHndlrs.html).


You are cordially-invited to join us to investigate the pytest Python 
testing framework.


"The pytest framework makes it easy to write small, readable tests, and 
can scale to support complex functional testing for applications and 
libraries."



Pre-requisites:

1 Head-set to ask questions and make contributions
2 Lab-/Log-/Note-book
3 Python 3.8+ installed
4 Ability to write intro-level Python program[me]s (at least)
5 Credentials to install from PyPi ("The Cheese Shop")
6 Preparedness to research, experiment, work with others...
As before, we will follow a café style of meeting. So, come prepared 
with a list of objectives you would like to achieve and a list of 
achievements you will be ready to share.



Possible (but far too many) topics:

- installing pytest (individual, system-wide, PyCharm, VSCodium, ...)
- TDD's (Test-Driven Development) red-green refactoring
- the Python assert-statement
- the project directory-tree and auto-discovery
- adding simple-tests
- running pytest
- reporting
- structuring the code-base to facilitate testing
- advantages/disadvantages of automated testing
- using a GAI to suggest/generate tests
- fixtures and dependencies (set-up and/or tear-down)
- scopes (function, class, module, session)
- parametrizing
- monkey-patching
- CI/CD chaining you've built
- plug-ins you're finding helpful
- coverage
- testing strategies
- other testing frameworks and aids
(open-ended - what would you like to add?)


Come to participate, learn-from, and help others!
Please RSVP at https://www.meetup.com/nzpug-auckland/events/298901851/


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-29 Thread dn via Python-list

On 30/01/24 05:15, Rich Shepard via Python-list wrote:

On Fri, 12 Jan 2024, Rich Shepard via Python-list wrote:


For my use 1) the salutation and email address (always with an '@') are
sequential and 2) I'm developing the script to extract both from the same
file.


I've looked at my Python books "Python Crash Course," "Effective Python,"
and "Python Tricks The Book" as well as web pages in my searches without
finding the answer to what may be a simple question: how to specify a
variable in one file that has its values in another file.

Specifically, how to I designate the salutation holder in the message file
and pass it the name value from the name/email address file?

If this explanation is not sufficiently clear I'll re-write it. :-)



It seems clear - but maybe we (all) misunderstand?

The books don't cover it - but is there a reason why they don't?


(Thunderbird did not thread this message with earlier ones, and it seems 
some time has passed/memory is fading - but hopefully have remembered 
content)



As said previously, the idea of two physical-files containing 
logically-related data (without any form of cross-reference between) is 
bad design.


In the current file, there is one physical structure and each person's 
details are logically-related by proximity. A long way from ideal, but 
workable (as you've described).


However, once split into two files, there is no way to guarantee that 
the two logically-related data-items (name and address) will continue to 
be related by their physical position in the respective files. Worse: 
whilst it would seem apparent that "Alice" from the names file might be 
related to the address "al...@domain.tld", how could one know if "Bob" 
actually corresponds to "list-mem...@domain.tld"?


This is why dicts, databases, etc, offer keys (as labels for 
data-items/dependent components)!



After a quick look at Eric's Crash Course, yes, his files-intro example 
(digits of pi) is unlikely to have any practical reality (and I work 
with statisticians and quants!). However, at the end of that chapter 
(10), there is mention of JSON files. A JSON version of the existing 
single-file structure will provide human-readable labeling of 
data-items, give better separation between individuals' data, and show 
how name and address are linked. Recommend solving 'the problem' that 
way! (as previously discussed by others 'here', IIRC)


Slatkin's Effective Python doesn't seem to discuss the basics of files 
at all (presumes such knowledge of the reader). It dives into important, 
but rather technical discussions, comparing strings and bytes - somewhat 
beyond the complexity-level of this discussion. That book does however 
include discussions such as "Prefer Multiple Assignment Unpacking over 
Indexing" (Item 6 - also points to Item 19) where relative-positioning 
(indexing in other words) is advised-against.



If you wish to persist with this two-file structure, please see earlier 
responses (again, IIRC) and discussion of file-merge operations. As 
these date back to mainframes and the days of storing files on mag-tape, 
I'd be surprised to see them discussed in 'modern' texts. However, the 
principle is: read a record from each file, do-the-business, read the 
next 'pair' of physically-related records, rinse-and-repeat.


If you require further assistance: how about showing a couple of 
relevant lines of the data-file(s) and the pertinent parts of the code, 
along with a description of what's going-wrong or not making sense to you?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-15 Thread dn via Python-list

On 15/01/24 21:13, Greg Ewing via Python-list wrote:

On 15/01/24 1:54 pm, dn wrote:

Soon after, Wirth simplified rather than expanded, and developed Pascal.


Before Pascal there was Algol-W, which Wirth invented as a rebellion
against how complicated Algol 68 was becoming.

When I first saw this I was stunned, then attracted to its simplicity, 
but then steered-away once realised that it needed 'more' to cope with 
'the outside world'.


Pascal was intended as a teaching language, and as such it was lacking
in practicality in a few spots. But it didn't need much tweaking to
make it a very useful language. UCSD Pascal, Turbo Pascal, Delphi, etc.
enjoyed a lot of popularity. A variant of UCSD was the main language
for Macintosh application development for a number of years.



Ironically, I didn't come across Pascal as a teaching-language.

Borland were trying to turn Turbo Pascal into a practical development 
environment, beyond teaching (as with others of their 'Turbo' series). 
As I say, it didn't float my business-world boat.
- not before I won a case a wine from Philippe Kahn's own vineyard for 
solving some 'interview question' and exchanging jokes with him, in 
French, at some Trade Show in London. Two surprises: one, that it 
actually turned-up a few weeks later, and two, that I (suddenly) had so 
many friends!


Ah, the good, old days...


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 14:45, Chris Angelico wrote:

On Mon, 15 Jan 2024 at 12:42, dn via Python-list  wrote:


On 15/01/24 14:33, Chris Angelico via Python-list wrote:

On Mon, 15 Jan 2024 at 12:12, dn via Python-list  wrote:

Here's another witticism I'll often toss at trainees (in many languages,
and especially in UX): just because we can do it, doesn't make it a good
idea!



Programming. We were so busy with whether we COULD that we didn't stop
to think if we SHOULD.

I think that's basically my whole life.


Don't be too hard on yourself.

My life-advice has always been "don't do anything I wouldn't do"
- which pretty-much gives you carte blanche.



I would NEVER give that advice to anyone. They would leave the dishes
unwashed, and a number of other problems :)


I'd soon have you sorted-out - except for one small problem: all the 
dishes have been done!


If you can get here before the rain, the lawn needs mowing...

--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 14:33, Chris Angelico via Python-list wrote:

On Mon, 15 Jan 2024 at 12:12, dn via Python-list  wrote:

Here's another witticism I'll often toss at trainees (in many languages,
and especially in UX): just because we can do it, doesn't make it a good
idea!



Programming. We were so busy with whether we COULD that we didn't stop
to think if we SHOULD.

I think that's basically my whole life.


Don't be too hard on yourself.

My life-advice has always been "don't do anything I wouldn't do"
- which pretty-much gives you carte blanche.

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 11:47, Chris Angelico via Python-list wrote:

On Mon, 15 Jan 2024 at 09:40, dn via Python-list  wrote:

The basic challenge came from my earlier (and blasé) repetition of the
Python refrain "everything in Python is an object". Which led to:

...


So, no, there's an "everything" which (might be) an object but which
cannot be used in that scenario.


More accurately, every VALUE in Python is an object. This does not
mean that syntax is an object. Very few languages would say that every
single grammatical element is a value.


+1

Thank you. This old-dog will try to re-learn that term...



Yes, it's sloppy to say "everything" is an object, but it's also
rather nonintuitive to claim that, therefore, syntax elements are all
objects. It's like claiming that everything that this dealership sells
is a car (or "everything in this dealership is a car"), and therefore
the dealership's name must itself be a car.


To say nothing of 'extended warranties'!
(and their dubious rationale)



That said, does anyone think that something like:

  for a_function( etc ) in iterable/iterator:

is acceptable?
- see both Python definition and (full-)quotation.

I've not come-across a language which does allow such - YMMV/mea culpa;
and am struggling to see how it could possibly be useful.


You could do something close to that:

for a_function(etc)[0] in iterable: ...

because an assignment target can contain an arbitrary expression
followed by the subscript.


Here's another witticism I'll often toss at trainees (in many languages, 
and especially in UX): just because we can do it, doesn't make it a good 
idea!




* Looking at the correspondent's email-address (cf 'handle') - and as an
unfair stereotype, raises the question of issues related to (English)
language-skills - which, arrogantly implies/assumes that native
English-speakers are all highly-capable. (?) A negative-interpretation
is to note his apparent intelligence, but wonder if failing to represent
others' comments fairly is deliberate, or carelessness. Is there an
irony in behaving/failing in such, whilst attempting to hold Python's
structure to some golden-ideal?


Seems likely.



--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 08:06, AVI GROSS via Python-list wrote:
...> You provided a way to create an anonymous function and that was not 
enough.

I wonder if you could throw in the new := walrus operator to similarly make
a named lambda function in a similar way.


Why would @Chris have anything to do with the 'walrus-operator'?

PS our interlocutor doesn't like colloquialisms such as these - despite 
them being near-and-dear to our hearts!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 01:28, Left Right wrote:

Second time to ameliorate wording-dispute in this thread! The original
phrase was: "[modified] BNF". Some of us have worked with various forms
and evolutions of BNF since back in the days of COBOL-60 proposals, and
know it when we see it!


OK, here are the conceptual differences between what Python grammar
language does and what you'd expect from anything that's based on BNF,
modified or not:

Python isn't a context-free language, so the grammar that is used to
describe it doesn't actually describe the language... so, it's a
"pretend grammar" that ignores indentation.  BNF is supposed to be
used to describe the language, it's not a "pretend" or "pseudo"
grammar, in a way we have at least two established grammar for
pseudo-code.

BNF and derivatives don't have an inherent mechanism for tiebreaks.
The mechanism is necessary because BNF rules can be tried in any
order.  Some grammar languages derived from BNF declare ambiguous
grammars invalid, some allow ambiguity, but say that the longest
prefix wins, and if there's still ambiguity after that, then such
grammar is invalid, some have special constructs to define "priority"
etc. My reading of Python grammar is that it works like PEG, where
rules are tried in the order they are defined.  This makes it less
expressive, but easier to work with.  This is, probably, the most
fundamental difference between the BNF family and the PEG family.

BNF and family languages rarely incorporate elements of Perl-like
regular expression parsing in the language (i.e. things like
lookaheads, lookbehinds etc.) This is more typical of the PEG family.

On top of this, the Python grammar language has a bunch of
"inventions" that are unique to it (I've never seen any other grammar
language use '.' in the same way Python uses it).  So, there's that
too.

Having worked with a bunch of different grammar languages, the one
used for Python isn't a recognizable BNF derivative.  I think the
authors used this as a description in the same way as today a lot of
programmers would use the word "IDE" to describe any text editor or
"REST" to describe any kind of server-client protocol over HTTP and so
on.  Or, how we'd use "Xerox" to name a copier machine, even if that
company didn't manufacture it, and even if the tech used for copying
is completely different.  And that's why I wrote that the grammar is
actually more like PEG, adding that it's neither, but seems to fall
more into that later category.


We are in broad-agreement. I'd enjoy the discussion, except that I can't 
see where it is leading or how it will benefit you...


Where we seem to differ is the length of time we've been part of the 
Python-world.


An important point is that languages are often described as 'living', 
because they evolve over time. I'm relieved to note that the youngsters 
in the family have stopped describing 'everything' as "awesome". That 
word, has taken-on aspects of the original meanings of "awful". The 
former being positive-factors, and the negative ascribed to the latter. 
However, we don't have to step far back into history to find that 
"awful" meant 'full of awe' or awe-inspiring - with no connotation of 
'good' or 'bad'. There was no need for a word with opposite-meaning, 
apart from "mundane".


Similarly, spoken-language often lacks precision. My CO, to this day, 
uses phrases like "all done" [with time for me to take a breath, 
followed by "except ...", eg "are we ready to leave for ...?". This 
drives me nuts. (the word "nuts" requires consideration too!) Thus, have 
learned to elicit the pertinent information with phrasing such as "what 
is left to be done?" rather than arguing the illogic between "all" and 
"except".


Python is not different. We're currently looking at version 3.12, which 
implies three major iterations of the language. Accordingly, when it was 
a 'green fields project', what may have been a pure and elegant 
expression of a language, has become "acquisitive". Sometimes these 
additions-and-alterations have required compromise, eg lack of elegance. 
Sometimes, it has been realised that there is a flaw, and things need to 
be improved, even removed.


You've made comments about BNF. Like Python, it is a 'language' (a bit 
of stretch, but...) which has also been pulled, poked, and perhaps 
contorted over time. It had a body of folk who understood its 
expression, and therefore it made sense to stick with some variation of 
it (even warts-and-all) rather than going with something 'new'.



All of which creates the sorts of issues described.

The PEG-parser is a comparatively-recent improvement - other aspects 
previously-mentioned.


I'm not going to touch "Perl".

Is there really some sort of standard-understanding/format for 
"pseudo-code"? (ISO?)


Yes, there's some 'pretense' (not sure I'd choose that exact term). 
However, it is working for the vast-majority. Perhaps after using Python 
for so long, I'm comfortable accepting such 'prete

Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 15/01/24 10:23, Chris Angelico via Python-list wrote:

On Mon, 15 Jan 2024 at 08:15, Left Right  wrote:

Python grammar rules prevent function definition from
appearing in left-hand side of the head of the for loop.  However, a
variable declaration, which is also a statement, is allowed there.


What is a "variable declaration" in Python? Please elaborate.


We may be in danger of disappearing down an unintended 'rabbit hole' 
with this side-discussion (he says, with graceful under-statement).



The basic challenge came from my earlier (and blasé) repetition of the 
Python refrain "everything in Python is an object". Which led to:


<<<
For example, you may say "functions in Python are
objects", but you cannot put a function definition in the head of the
for loop clause.
>>>

Which is logical - to some degree, and in-isolation.

for def a_function( etc )... in iterable/iterator:

does not make sense. The 'head' (a more generic name, where Python says 
"target_list", that refines down to 'something which can identify the 
generated-value'.


So, no, there's an "everything" which (might be) an object but which 
cannot be used in that scenario.



Two "howevers":

However, instead of looking at the narrow clause, (third comment about 
wording not being taken as an whole!!!)* the full quotation was:


<<<
In Python, everything is an object. As long as the LHS is a legal-object 
which  makes sense for the situation, it can be used.

>>>

Context!

However, from the docs: "A function definition defines a user-defined 
function object (see section The standard type hierarchy)". Accordingly, 
is a function-definition an object? No! It defines an object.


That said, does anyone think that something like:

for a_function( etc ) in iterable/iterator:

is acceptable?
- see both Python definition and (full-)quotation.

I've not come-across a language which does allow such - YMMV/mea culpa; 
and am struggling to see how it could possibly be useful.


In-turn, how this discussion could become profitable...


* Looking at the correspondent's email-address (cf 'handle') - and as an 
unfair stereotype, raises the question of issues related to (English) 
language-skills - which, arrogantly implies/assumes that native 
English-speakers are all highly-capable. (?) A negative-interpretation 
is to note his apparent intelligence, but wonder if failing to represent 
others' comments fairly is deliberate, or carelessness. Is there an 
irony in behaving/failing in such, whilst attempting to hold Python's 
structure to some golden-ideal?



Web.Refs:
https://docs.python.org/3/reference/compound_stmts.html#the-for-statement
https://docs.python.org/3/reference/simple_stmts.html#grammar-token-python-grammar-target_list
https://docs.python.org/3/reference/compound_stmts.html#function-definitions

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-14 Thread dn via Python-list

On 14/01/24 16:48, Chris Angelico wrote:

On Sun, 14 Jan 2024 at 14:43, dn via Python-list  wrote:

Similarly, whilst we could write:

a, b, c = 1, 2, 3



I would only do this when it aligns particularly well with the
algorithm being implemented. For example, you could start a Fibonacci
evaluator with "a, b = 0, 1". Otherwise, there's not all that much
reason to unpack three constants in this way.

(Though I am much more likely to use multiple initialization to set a
bunch of things to the SAME value, lilke "a = b = c = 0".)


Neatly stated!

--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-13 Thread dn via Python-list

On 13/01/24 00:11, Left Right via Python-list wrote:

To people discussing BNF:

The grammar language Python uses is *very* far from BNF. It's more
similar to PEG, but even then it's still quite far.  Python's grammar
is just its own thing, which makes it harder to read, if you are
already familiar with other more popular formats.


Second time to ameliorate wording-dispute in this thread! The original 
phrase was: "[modified] BNF". Some of us have worked with various forms 
and evolutions of BNF since back in the days of COBOL-60 proposals, and 
know it when we see it!


From the 'book of words': <>>

https://docs.python.org/3/reference/introduction.html#notation

Yes it is hard to read - and even harder to learn-from; which is why 
@Chris gave advice about preferring tutorials/text.


Just because there are other (more popular?) formats, doesn't make the 
one used here 'wrong'. In the same way that Python code differs from 
'the same' in other languages.


Putting it another way: if what Python is doing is wrong in your 
opinion, you are in the wrong place (for you).


That is not to say that Python has everything 'right'. One of my own 
bug-bears is very similar - that the string formatting 'mini-language' 
(https://docs.python.org/3/library/string.html#formatspec) does not 
follow the same rules about white-space as everything covered by the PEG 
Parser.


BTW the PEG Parser is relatively new to Python. IIRC there was comment 
at the time of its first application, that some 'other' areas of Python 
might take a while to be converted-over.




I've also found bugs in Python parser before, so had this turned out


Sorry, didn't recognise your email-handle - not that I'm a Python 
Core-Dev, and pretty much ignore the "Ideas" list these days. Must have 
missed your previous contributions...




to be a real issue, this wouldn't have been the first time.  There are
plenty of weird corners in Python grammar that allow unexpected
programs to parse (and sometimes even run!), and these are very often
connected to assignments, because, in general, assignments in Python
are very elaborate and hard to describe / conceptualize about.  The
most popular example I've even seen used in coding interviews (which I
think is a silly gimmick, but that's kind of the whole point of a lot
of these interviews...) is:

 x = [...]
 for x[i] in x: print(i)

Which is not an assignment by itself, but the "weirdness" results from
the loop syntax sharing definitions with the "destructuring bind"
style of assignment (i.e. where the left-hand side can be an arbitrary
complex expression).


You're right. (also about stupid 'interviewing' ideas) If someone asked 
me this, I'd respond by asking if that was the standard of code they 
work towards - and depending upon that answer would either walk-out or 
refer the matter to a more senior manager!



In Python, everything is an object. As long as the LHS is a legal-object 
which  makes sense for the situation, it can be used.


Also, an identifier (whether x, i, or x[ i ]) should not only be 
considered to be its own object, but is best regarded as a pointer to 
some value. This is how we can have an 'immutable' tuple 'containing' a 
mutable list (for example) - such that elements of that list may be 
changed, despite being 'part of' an immutable construct!


Programs are read by people. If something is a "weirdness", then 
chances-are it won't survive a CodeReview/a professional team's 
expected-standard. Not limited to Python-code!




I was surprised, for example, to learn that "as" in "with_stmt" isn't
shared with "as" in "except_block" (so, from the grammar perspective,
these are two different keywords), and that asterisk in "except_block"
isn't shared with "star_target" (also weird, since you'd think these
should be the same thing).  In general, and by and large, if you look
at Python's grammar there are many "weird" choices that it makes to
describe the language which seem counterintuitive to the programmer
who tries to learn the language from examples (i.e. context-depending
meaning of parenthesis, of asterisk, of period etc.)  Having been
exposed to this, you'd start to expect that some of this weirdness
will eventually result in bugs, or at least in unexpected behavior.


You're right. It is potentially confusing when the same word/symbol is 
used in different contexts.


I've heard similar questions from learners, but not had anyone trying to 
mis-use something extrapolating from how the 'same' is used elsewhere. YMMV!


It's the context part that's important to remember. If someone calls you 
"mate", that has different connotations depending upon whether you're 
friends, you're on a Navy ship, or in a more intimate situation - indeed 
there are some cultures in which the word "mate" is not used to mean 
'friend' at all. Which is (more) right? Which wrong?


Perhaps you're aiming for, or even used to, a more 

Mtg: Object-Oriented VacExcHndlrs (UTC+13)

2024-01-13 Thread dn via Python-list
Let's meet on Wednesday (17Jan, 1600 NZDT (UTC+13), wearing a head-set) 
to talk about Object-Oriented everything. Is O-O worthwhile, or does is 
it just a load of guys running around and getting no-where?


NB this is not a formal PUG-meeting. It's part of the "Vacation 
Exception Handlers" series 
(https://danceswithmice.info/Python/2024/VacExcHndlrs.html) - 
virtual-gatherings for folk left-behind to keep the wheels turning, 
whilst everyone else swans-off sunning themselves...


(non-Kiwis please remember: it's not just school vacation, but 
summer-time down-under. Wish you were here?)


Café-style approach, so there will be no formal presentation. All 
welcome. No presumption of knowledge/skill. This gathering is for 
everyone, from Beginner to Python-Master.



Is Python an Object-Oriented language?
Why does Python use (what appear to be) procedural constructs for so 
many of its core functions, eg len(a_list) rather than a_list.length() 
and sqrt(a_number) rather than a_number.sqrt()?

Why do pythonista say "everything in Python is an object"?
Is it faster to write in an OOP-style and/or does OOP-code run faster? 
If not, why bother?
- insert your question here: What do you want to know? What has been 
bothering you about OOP (or O-O in Python) that you'd like to settle?


To join us (we don't bite!), please RSVP at 
https://www.meetup.com/nzpug-auckland/events/298536620/


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-13 Thread dn via Python-list

On 12/01/24 08:53, Rich Shepard via Python-list wrote:

On Thu, 11 Jan 2024, Piergiorgio Sartor via Python-list wrote:


Why not to use bash script for all?


Piergiorgio,

That's certainly a possibility, and may well be better than python for this
task.


(sitting in a meeting with little to occupy my mind, whilst tidying 
email-InBox came back to this conversation)



In the bare-description of the task, I might agree to sticking with 
BASH. The OP did say that the output from this will become input to a 
sed/mailx task!

(we trust, does not involve spamming innocent folk)

However, that task could also be accomplished in Python. So, unless 
there is an existing script (perhaps) quite why one would choose to do 
half in Python and half in BASH (or...) is a question.



Because this is a Python forum, do the whole thing in one mode - our mode!

Previous suggestions involved identifying a line by its content.

Could use a neat state-transition solution.

However, there is no need to consider the input-data as lines because of 
the concept of "white-space", well-utilised by some of Python's built-in 
string-functions. See code-sample, below.


As mentioned before, the idea of splitting the one file (data-items 
related by serial-progression) and creating two quite-separate 
data-constructs (in this case: one holding the person's name in one file 
and the other the person's email-address in another) which are related 
'across', ie line-by-line, is an architectural error?horror. Such would 
be hard to maintain, and over-time impossible to guarantee integrity. 
Assuming this is not a one-off exercise, see elsewhere for advice to 
store the captured data in some more-useful format, eg JSON, CSV, or 
even put into a MongoDB or RDBMS.



** code

""" PythonExperiments:rich.py
Demonstrate string extraction.
"""

__author__ = "dn, IT&T Consultant"
__python__ = "3.12"
__created__ = "PyCharm, 14 Jan 2024"
__copyright__ = "Copyright © 2024~"
__license__ = "GNU General Public License v3.0"

# PSL
import more_itertools as it

DATA_FILE = "rich_data_file"
READ_ONLY = "r"
AS_PAIRS = 2
STRICT_PAIRING = True


if __name__ == "__main__":
print("\nCommencing execution\n")

with open( DATA_FILE, READ_ONLY, ) as df:
data = df.read()

data_as_list = data.split()
paired_data = it.chunked( data_as_list, AS_PAIRS, STRICT_PAIRING, )

for name, email_address in paired_data:
# replace this with email-function
# and/or with storage-function
print( name, email_address, )

print("\nTerminating")

** sample output

Calvin cal...@example.com
Hobbs ho...@some.com
...

**

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-11 Thread dn via Python-list

On 12/01/24 12:56, Chris Angelico via Python-list wrote:

On Fri, 12 Jan 2024 at 08:56, Left Right via Python-list
 wrote:


By the way, in an attempt to golf this problem, I discovered this,
which seems like a parser problem:


When you jump immediately to "this is a bug", all you do is make


"seems"!

but yes, it is a (much) less-likely explanation.



yourself look like an idiot. Unsurprisingly, this is NOT a bug, this
is simply that you didn't understand what was going on. The grammar
isn't easy to read, and it's usually better to read the documentation
instead.


Those of us who studied Computer Science may well have been 
taught/expected to learn how to read [modified] BNF - indeed to have 
worked in that (cf coding in Python).


Accordingly, the English text is likely easier to understand, but 
sometimes the BNF offers finer-detail or can be used to clarify some 
mis- or insufficiently-understood aspect of the text. IMHO/YMMV/etc...




(Plus, golfing isn't really a goal in Python, and you didn't  shorten
the code by much at all. Good job.)


I took my hat off to the poster, being prepared to dive-in and do this. 
Accordingly, was more than happy to help set him/her back onto 'the 
straight and narrow'.


(yes it was a BNF-failing - which, credit where credit's due, I think 
was realised at the same time as response was typed)


How many others just want us to do all their thinking for them?
(there's a rude comment about wiping noses - but probably a step too far 
wrt the CoC)


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Extract lines from file, add to new files

2024-01-11 Thread dn via Python-list

On 12/01/24 10:33, Left Right via Python-list wrote:

By the way, in an attempt to golf this problem, I discovered this,
which seems like a parser problem:

This is what Python tells me about its grammar:

with_stmt:
 | 'with' '(' ','.with_item+ ','? ')' ':' block
 | 'with' ','.with_item+ ':' [TYPE_COMMENT] block
 | ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block
 | ASYNC 'with' ','.with_item+ ':' [TYPE_COMMENT] block

with_item:
 | expression 'as' star_target &(',' | ')' | ':')
 | expression

 From which I figured why not something like this:

with (open('example.txt', 'r'), open('emails.txt', 'w'),
open('salutations.txt', 'w')) as e, m, s:
 for line in e:
 if line.strip():
 (m if '@' in line else s).write(line)

Which, surprise, parsers! But it seems like it's parse is wrong,
because running this I get:

❯ python ./split_emails.py
Traceback (most recent call last):
   File "/home/?/doodles/python/./split_emails.py", line 1, in 
 with (open('example.txt', 'r'), open('emails.txt', 'w'),
open('salutations.txt', 'w')) as e, m, s:
TypeError: 'tuple' object does not support the context manager protocol

It seems to me it shouldn't have been parsed as a tuple. The
parenthesis should've been interpreted just as a decoration.

NB. I'm using 3.11.6.
A series of comma-separated items will be parsed as a tuple (some people 
think it is bounding-parentheses which define).


In this case, the issue is 'connecting' the context-manager "expression" 
with its (as) "target". These should be more-closely paired:-


with ( open( 'example.txt', 'r', ) as e,
   open( 'emails.txt', 'w', ) as m,
   open( 'salutations.txt', 'w', ) as s
   ):

(NB code not executed here)


A data-architecture of having related-data in separated serial-files is 
NOT recommendable!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: A problem with str VS int.

2023-12-12 Thread dn via Python-list

On 12/12/23 21:22, Steve GS wrote:

With all these suggestions on
how to fix it, no one seems to
answer why it fails only when
entering a two-digit number.
One and three work fine when
comparing with str values. It
is interesting that the
leading 0 on a two digit
worked.  Still, one digit and
three digit work but not two.

This is now more of a
curiosity as I did use the
integer comparisons.



Emphasis on the word "seems"!

Did you try running the code provided earlier? Did you notice that such 
illustrated what happens when using strings which appear as numbers, and 
showed how a three digit number (expressed as a string) may well precede 
a two- (or even a one-) digit number in the same form - and that the 
end-result of the sequence of integers is quite-different to the 
sequence of integer-values expressed as strings!


Why does this happen? Because of the way data is encoded. It is language 
independent. The definition of order or sequence is called "collation".


"Comparisons" establish relative-sequence. You will find some handy 
explanations of how comparisons work (eg equals or less-than) in the 
Python manual.


After working through those three steps, if there's something that's 
still mystifying, please refine the question...



Web.Refs:
https://en.wikipedia.org/wiki/Collation
https://docs.python.org/3/reference/expressions.html?highlight=comparison#value-comparisons
https://docs.python.org/3/howto/sorting.html?highlight=sort


--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: A problem with str VS int.

2023-12-09 Thread dn via Python-list

On 10/12/23 15:42, Steve GS via Python-list wrote:

  If I enter a one-digit input or a three-digit number, the code works but if I 
enter a two digit number, the if statement fails and the else condition 
prevails.

tsReading = input("   Enter the " + Brand + " test strip reading: ")
 if tsReading == "": tsReading = "0"
 print(tsReading)
 if ((tsReading < "400") and (tsReading >= "0")):
 tsDose = GetDose(sReading)
 print(tsReading + "-" + tsDose)
 ValueFailed = False
 else:
 print("Enter valid sensor test strip Reading.")

I converted the variable to int along with the if statement comparison and it 
works as expected.
See if it fails for you...


It works as expected (by Python)! This is how strings are compared - 
which is not the same as the apparently-equivalent numeric comparison.


Think about what you expect from the code below, and then take it for a 
spin (of mental agility):


values = [ 333, 33, 3, 222, 22, 2, 111, 11, 1, ]
print( sorted( values ) )
strings = [ "333", "33", "3", "222", "22", "2", "111", "11", "1", ]
print( sorted( strings ) )


The application's data appears numeric (GetDose() decides!). 
Accordingly, treat it so by wrapping int() or float() within a 
try-except (and adjusting thereafter...).



"But wait, there's more!"
(assuming implement as-above):

if 0 <= ts_reading < 400:

1 consistent 'direction' of the comparisons = readability
2 able to "chain" the comparisons = convenience
3 identifier is PEP-008-compliant = quality and style

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: How/where to store calibration values - written by program A, read by program B

2023-12-06 Thread dn via Python-list

On 7/12/23 07:12, MRAB via Python-list wrote:

On 2023-12-06 12:23, Thomas Passin via Python-list wrote:

On 12/6/2023 6:35 AM, Barry Scott via Python-list wrote:



On 6 Dec 2023, at 09:32, Chris Green via Python-list 
 wrote:


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.


JSON will allow you to nest dictionaries.

{
 'KEY1': {
 'a': v1
 'c': v3
 'd': v4
 }
 'KEY2': {
  'a': v7
  'b': v5
  'd': v6
 }
}

Personally I would not use .ini style these days as the format does 
not include type of the data.


Neither does JSON.  Besides, JSON is more complicated than necessary
here - in fact, your example isn't even legal JSON since lines are
missing commas.

Fun fact - for at least some, maybe most, JSON files, using eval() on
them is hugely faster than using Python's standard JSON library.  I
learned this when I wanted to ingest a large browser bookmarks JSON
file. It wouldn't matter for a much smaller file, of course.


It would be safer if you used literal_eval.


Ah, memories of Python2...

Does this little hack still work?

What about True/False cf true/false?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


NZPUG Mtg: Making Python faster, and "Dependency Inversion"

2023-11-22 Thread dn via Python-list

Virtual meeting: Wednesday 6 December, 1815 for 1830 NZDT/UTC+13
Book at https://www.meetup.com/nzpug-auckland/events/295433876/


1 Making Python faster - using type hints

Tushar will lead us through:

A brief history of type hints
Using type checkers to verify your type hints
Compiling type checked Python to make it faster
Some examples of libraries and the speedups they get from type hints

We'll be looking at mypy/mypyc.

Audience Level: intermediate, ie understand Python constructs, 
functions, control flow, etc.


Tushar has been a long term Python developer, OSS contributor, author 
and speaker. He has been working with static analysis and type checkers 
for the past 3 years, and has contributed to various PSF-projects such 
as black and mypy.



2 SOLID's Dependency Inversion Principle

Olaf will complete the current Software Craftsmanship series on the 
SOLID Principles with a session on the Dependency Inversion Principle. 
This one is particularly fascinating, because at first-glance the 
inversion seems to be asking us to do things backwards. With 
understanding, we realise that it is an impressive device enabling us to 
focus on what is needed by the 'layer' of more valuable components, 
rather than the lower-level, eg UIs and external interfaces (need 
refresher? see https://www.bmc.com/blogs/solid-design-principles/)


Audience Level: advanced, ie understand programming constructs, 
patterns, principles, etc.


Olaf needs no introduction having generously brought us the earlier 
sessions in his "Software Craftsmanship" series over the last two years. 
Let's complete this exercise in dogged-persistence and round things off 
neatly - if you remember, this talk was originally scheduled last month, 
but technical-gremlins got in the way! Also, please tell us what topics 
you'd like to cover at this skill-level in future...



Please come, and come with a collegial frame-of-mind. Questions and 
conversation will be the order of the day. If you are more confident in 
Python, your constructive advice, suggestions, and alternate approaches 
will be valued ...


--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Newline (NuBe Question)

2023-11-15 Thread dn via Python-list

On 15/11/2023 20.25, Grizzy Adams via Python-list wrote:

Hi & thanks for patience with what could be simple to you

Have this (from an online "classes" tutorial)


There are lots of on-line classes!



--- Start Code Snippit  ---

students = []
grades = []
for s in geographyClass:
students.append(geographyStudent(s))
for s in students:
 grades.append(s.school)
 grades.append(s.name)
 grades.append(s.finalGrade())
 if s.finalGrade()>82:
 grades.append("Pass")
 else:
 grades.append("Fail")
print(grades)

--- End Code Snippit  ---

I have extended (from tutorial) it a bit, I would really like to have a newline

at end of each record, I have searched (and tested) but cant get "\n" to give a

newline, I get "Mydata\n"

Do I need to replace "append" with "print", or is there a way to get the
newline in as I append to list?


Don't know how "Mydata..." results - where is it in the code.

What do you see when grades is printed?
Do you really want data-values all mashed together?

Yes, what changed after removal of all the .append()-s, and instead, 
within the (second) for-loop print( school, name, ... ) was used?


Is it easier to go on from there?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Clearing the Deque • Picturing Python’s `deque` data structure

2023-11-07 Thread dn via Python-list
You will be welcome to join us at our next (hybrid) meeting: Wednesday, 
15 November 2023, 1815~2030 NZDT (0515~0730 UTC).



How often do you use a deque*? “Not very” is a common answer. Perhaps 
you’ve never used it. In this presentation, Stephen won’t try to 
convince you to use it more often. Instead, he’ll present a different 
perspective on what this data structure is, and how it differs from a 
list. The presentation will compare deques and lists in a visual manner, 
to help us understand why we may need a deque in certain situations. 
We’ll also explore some demonstration examples to highlight the 
differences in performance between the two data structures in different 
scenarios.

*pronounced like “deck"

Audience: This presentation is ideal for those who have either never 
heard of deque, or have heard of it but never really used it or 
understood why it’s needed. The more experienced may find the visual 
story insightful.


Stephen used to be a physicist, which is where he learned programming. 
After working in science and academia for over a decade, he decided to 
escape before it was too late. Since then, has focused exclusively on 
teaching coding and communicating about Python. A big part of his day is 
busy with running Codetoday—we teach Python coding to children between 7 
and 16 years old (https://www.codetoday.co.uk/). He also runs courses 
for adults and corporate training programs, and particularly, writing 
about Python. He writes the articles he wished he had when learning. He 
publishes articles at The Python Coding Stack 
(https://thepythoncodingstack.substack.com/) and also wrote an online 
book (soon to be in other formats, too) for beginners, The Python Coding 
Book (https://thepythoncodingbook.com/).



Please RSVP on Meetup.com (NZPUG Auckland Branch): 
https://www.meetup.com/nzpug-auckland/events/295433874/


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: fCONV_AUSRICHTG is not defined - Why?

2023-11-07 Thread dn via Python-list

On 08/11/2023 06.47, Egon Frerich via Python-list wrote:

I've no idea why this happens. In a module there are lists and definitions:

...


     ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder])
   File "/home/egon/Entw/Geldspur/geldspur/gui/GUI_Konfig.py", line 90, 
in 

     ["%s%s%s " % (i[fCONV_AUSRICHTG], i[fLG2], i[fTYP]) for i in Felder])
NameError: name 'fCONV_AUSRICHTG' is not defined

You see "Felder" and with "0 0 3 4" the correct value 4 for 
fCONV_AUSRICHTG. But there is the NameError.


What does  mean? Is there a change from python2 to python3?


Works for me (Python 3.11 on Fedora-Linux 37)
- both as a script, and simple/single import.

What happens when you extract the second dimension's definitions into a 
module of their own, and import that (with/out less-sophisticated join)?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Safe package removal

2023-11-05 Thread dn via Python-list

After thread: "pip/pip3 confusion and keeping up to date"


Over the years?centuries, have added various packages, using all of:

- distribution-installer (dnf/yum - per apt-get)
- su pip install, and
- (user) pip install

Because Fedora-Linux can be upgraded in-place. an amount of 'crud' 
hangs-about 'forever'.


Accordingly, python -m pip list --outdated shows about as many entries 
as python - m pip list!


Have (comparatively recently) standardised that projects not inside a VM 
or Container, will be managed by Poetry. (It's working well!)



Q1
Can all (user) pip installs be safely removed, 'just like that'?

Q2
How can one ascertain if system (su/sudo) pip installed packages can be 
removed - or are used by the op-sys/some important application?


Q3
Similarly, if one can uninstall those originally installed using the 
distribution-installer, or if something, somewhere, will 'break'?

(yes, there's an upgrade to Fedora 38 in "The Backlog")

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking if email is valid

2023-11-02 Thread dn via Python-list

On 02/11/2023 20.28, Simon Connah wrote:


I'm not sure that would be practical. As I'm setting up a mailing list server I 
don't know if someone in the future is going to need to use one of those 
aliases and testing manually would be tedious.


Please re-read.
Discussion is about "closeness".
Thus, what you might expect from email servers and Admins, NOT what you 
should do. That part should be quite evident by now!


--
Regards,
=dn

--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking if email is valid

2023-11-02 Thread dn via Python-list




On 02/11/2023 19.56, Chris Angelico via Python-list wrote:

On Thu, 2 Nov 2023 at 17:47, Simon Connah  wrote:


My goal is to make a simple mailing list platform. I guess I could just send 
email to an address and if it bounces then I can remove it from the database. 
Thing is I'm not sure how close to a real email address an email has to be in 
order to be bounced. If it was completely wrong it might just swallowed up.



Every address is completely separate. There is no "closeness". Just
send email to an address.



Agreed.

However, with names that are frequently misspelled or which are 
commonly-spelled slightly differently, the 'trick' is to anticipate 
problems and set up aliases which forward messages to the correct address*.


eg Kelvin -> Kevlin
Niel, Neal, Neale (etc) -> Neil

(in the same way that GoodLookingGuy@mydomain -> me,
or (more likely) MailAdmin -> me)


* however, this can end-up perpetuating the mistake, rather than 
correcting...


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking if email is valid

2023-11-02 Thread dn via Python-list

On 02/11/2023 19.46, Simon Connah via Python-list wrote:

On Thu, 2 Nov 2023 at 05:21, Simon Connah via Python-list
python-list@python.org wrote:




Could someone push me in the right direction please? I just want to find out if 
a string is a valid email address.









There is only one way to know that a string is a valid email address,
and that's to send an email to it.




What is your goal though? For example, if you're trying to autolink
email addresses in text, you don't really care whether it's valid,
only that it looks like an address.




My goal is to make a simple mailing list platform. I guess I could just send 
email to an address and if it bounces then I can remove it from the database. 
Thing is I'm not sure how close to a real email address an email has to be in 
order to be bounced. If it was completely wrong it might just swallowed up.


Exactly!

Build a complementary script which inspects the returned/bounced 
messages, and removes those addresses.


Given that the list of addresses is built from people signing-up in the 
first place, one has to presume that people know their own addresses and 
can type - there's no real defence against 'stupid'*. It's not as if you 
are making-up addresses yourself (in many jurisdictions it is illegal 
without opt-in).


An email address: account@domain, has to be accurate in two ways:
1 the domain - otherwise the DNS (Domain Name System) won't be able to 
locate the destination email server
2 the account - otherwise the email server won't know to which mail-box 
the message should be delivered.


The (1) is why there was some suggestion of using MX records (but may as 
well just send the message).


The problem with (2) is that some servers will 'bounce' a message, but 
others will let it die silently (not wanting to add to email-spam by 
sending stuff 'back' if the message was spam in the first place!)


The exception to (2) is a "catch-all" address, which accepts every 
message not addressed to a (legal) mail-box. These are sometimes used to 
deal with messages addressed to a staff-member who has left (for 
example). However, are somewhat problematic because they pick-up tons of 
garbage (eg earlier today I received a message to 456...@domain.tld. 
This is not, and never has been, a mail-box on the domain; but would 
drop into a catch-all mail-box.


It would be an unusual MailAdmin inspecting a catch-all address, who 
would return a mis-addressed email to its source. If the message was 
addressed to s...@domain.tld, I'd be more likely to assume it was for 
you, and forward it to you (in the expectation that you'd fix the 
problem with the sender...). However, ...


There are some large businesses doing what you've outlined. They have 
not solved this problem - and not through lack of trying!



* as fast as you make something idiot-proof, the world will show you an 
'improved' class of idiot!

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking if email is valid

2023-11-01 Thread dn via Python-list

On 02/11/2023 00.35, Simon Connah via Python-list wrote:
OK. I've been doing some reading and that you should avoid regex to check email addresses. 


This operation used to be a BIG THING back in the days of 'everyone' 
building PHP web-sites. When there were only a handful of TLDs 
(top-level domain names, eg the country-codes* such as .nz and .uk plus 
the generics such as .com and .net. Accordingly, one could hold the 
entire list for convenience of checking. However when IANA (the outfit 
responsible for the Root Zone Database and especially ICANN realised 
that there was money to be made, they allowed more and more TLDs. 
Keeping-up became a rat-race!


Indeed, I've held another .info domain for twenty years, and used to 
suffer for my 'bleeding edge' daring - quite recently someone (who 
should remain name-less, and a few other less-es) sent me an email 
telling me how to log-in, but their log-in process wouldn't accept the 
'illegal' address. Um...


All together now: "a little bit of knowledge is a dangerous thing"!


So what I was thinking was something like this:


if type(email_recipient) != email.message.Message:

I just don't know why that particular line isn't working.


Will need more context. What is the objective? What is the 
source/pre-processing of these data-items. (etc)




* Left-out .au, (a less important geo-TLD) to wind-up @Chris...

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Too Broad of an exception

2023-10-25 Thread dn via Python-list

On 26/10/2023 04.49, rsutton via Python-list wrote:

On 10/25/2023 11:06 AM, Stefan Ram wrote:

r...@zedat.fu-berlin.de (Stefan Ram) writes:

outer quotation marks) prints some prominent exception types. After

...


   "Manually removing" above was meant to be a fast first pass,
   where I only excluded exception types that were obviously
   inappropriate. It is now to be followed by a search for the
   appropriate exception types among those exception types left.



@Rene & @Stefan,
I really appreciate the guidance provided.  By replacing Exception with 

...


It would appear that (at least one message) did not make it to email - 
neither to the list-archive.


People wishing to learn are unable to benefit a response, if it is not 
sent to the list!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: return type same as class gives NameError.

2023-10-22 Thread dn via Python-list

On 23/10/2023 04.50, Antoon Pardon via Python-list wrote:

I have the following small module:

=-=-=-=-=-=-=-=-=-=-=-= 8< =-=-=-=-=-=-=-=-=-=-=-=-=

from typing import NamedTuple, TypeAlias, Union
from collections.abc import Sequence

PNT: TypeAlias = tuple[float, float]

class Pnt (NamedTuple):
     x: float
     y: float

     def __add__(self, other: PNT) -> Pnt:
     return Pnt(self[0] + other[0], self[1] + other[1])

=-=-=-=-=-=-=-=-=-=-=-= >8 =-=-=-=-=-=-=-=-=-=-=-=-=

But when I import this, I get the following diagnostic:

Traceback (most recent call last):
   File "", line 1, in 
   File "/home/sisc/projecten/iudex/problem.py", line 10, in 
     class Pnt (NamedTuple):
   File "/home/sisc/projecten/iudex/problem.py", line 14, in Pnt
     def __add__(self, other: PNT) -> Pnt:
  ^^^
NameError: name 'Pnt' is not defined. Did you mean: 'PNT'?


Can someone explain what I am doing wrong?


What happens when the advice is followed?

Not sure why declare type-alias and then don't use it, but if insist on 
using class-name will be making a "forward-reference" (because class has 
not yet been fully defined) - see 
https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#forward-references


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Where I do ask for a new feature

2023-10-20 Thread dn via Python-list

On 21/10/2023 01.32, Thomas Passin via Python-list wrote:

On 10/19/2023 11:16 PM, Bongo Ferno via Python-list wrote:
On Thursday, October 19, 2023 at 11:26:52 PM UTC-3, avi.e...@gmail.com 
wrote:


There are many ways to make transient variables that disappear at 
some time
and do we need yet another? Yes, you can create one of those ways but 
what

is the big deal with deleting a variable when no longer used?


Assigning a variable to something can be anything else than a temporal 
alias.
A with statement makes clear that the alias is an alias and is local, 
and it automatically clears the variable after the block code is used.


Python clutters the variable space with vars that are needed only on 
certain places, and an alias doesn't has a scope.
Convenient alias are short names, and short names are limited in 
quantity. If the space is cluttered with short alias, it opens risks 
for wrong utilization.


Its like writing a "for i" in a list comprehension and having to worry 
if "i" was already used in another place..


If a name is temporarily needed in a certain place and in a certain 
scope then reusing the name shouldn't be a problem.


Agree. Surely, the only time we use a name like "i" is in a throw-away 
context?


Under many circumstances Python will let us use "_" in place of a 
named-identifier - which enables both us and Python to remember its 
short-lived value/local-only use.


Using an alias MERELY for the convenience of a shorter-name suggests two 
things: 1 lack of a competent editor/IDE, 2 lack of imagination in 
choosing names (perhaps one of THE skills of programming!)


Yes, there are other languages which enforce a limited-scope on 
data-items created within or as part of a code-structure - and it IS a 
handy feature! On the other hand, Python's apposite stance can be useful 
too, eg trivial toy-example:


# list_of_stuff = ...

for n, element in list_of_stuff:
if element == target:
break

# now element == target, so "element" is probably not that useful
# but "n" is the index of the target-element, which may be
# (there are other ways to accomplish same)


Please take a look at the ideas behind "Modular Programming". This 
encourages the breaking-up of monolithic code and its "cluttered" global 
namespace, into potentially-independent code-units. The outlined-problem 
is solved by the independent scope of those code-units (in Python: 
modules, classes, functions, and "if __name__ == "__main__":".
(to say nothing of the coder's virtues of "re-use", the "Single 
Responsibility Principle", "do one thing, and do it well", Law of 
Demeter, ...)


Personal comment: my habit is to break specs into many classes and 
functions - sometimes more-so than others might prefer. Cannot recall 
when last had that hard-to-locate bug of unwittingly re-using a name/alias.

(apologies: not a boast - a recommendation for going modular)

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-04 Thread dn via Python-list

On 04/10/2023 19.41, Chris Angelico via Python-list wrote:

On Wed, 4 Oct 2023 at 15:27, dn via Python-list  wrote:

- should the class have been called either;

  class SomethingSingleton():

or a Singleton() class defined, which is then sub-classed, ie

  class Something( Singleton ):

in order to better communicate the coder's intent to the reader?


TBH, I don't think it's right to have a Singleton class which is
subclassed by a bunch of different singletons. They aren't really
subclasses of the same class. I could imagine Singleton being a
metaclass, perhaps, but otherwise, they're not really similar to each
other.


I'm with you on this - should have made Singleton() an ABC.

Yes, would only be a skeleton around which concrete singleton classes 
could be built.


Like you, I v.rarely use them - but which means that the ABC is useful 
because it would save me from having to remember the curly-bits 
all-over-again...


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-03 Thread dn via Python-list

On 02/10/2023 00.57, Karsten Hilbert via Python-list wrote:

Sorry for having conflated the core of the matter with all
the Borg shenanigans, that's where I found the problem in my
real code, so there :-)


The first question when dealing with the Singleton Pattern is what to do 
when more than one instantiation is attempted:


- silently return the first instance
- raise an exception


The 'problem' interpreting the original code was that the 'Borg 
Pattern', is not limited in number, but is where some class-attribute 
list (or dict) is used to enable all instances to be aware of each of 
the others (IIRC).


Is choosing names as important as selecting/implementing smart algorithms?



Consider this:

#
class Surprise:
def __init__(self, with_type_annotation=False):
if with_type_annotation:
try:
self.does_not_exist:bool
print('does_not_exist does exist')
except AttributeError:
print('does_not_exist does not exist')
return

try:
self.does_not_exist
print('does_not_exist does exist')
except AttributeError:
print('does_not_exist does not exist')

Surprise(with_type_annotation = False)
Surprise(with_type_annotation = True)
#

Is this how it is supposed to be ?


Wasn't this answered earlier? (@Mats)

That self.does_not_exist:bool isn't interpreted by Python to mean the 
same as self.does_not_exist.




...and so we're addressing the important question: the try-test is for 
existence, cf for
some value.

This can also be achieved by using the attribute in a legal expression, eg:

...

Might this remove the confusion (ref: @Mats):

 self.already_initialized:bool == True


Not for me as that would _create_ already_initialized on the
instance. It would not allow me to test for it.


Which seems akin constructs for generating compatibility
between versions.


versions of ?


Of the language. Sometimes one tests for existence of a given
class in a module and defines said class oneself if it does
not exist. But that's leading astray.


What is the intent: a class where each instance is aware of every other 
instance - yet
the word "Singleton" implies there's only one (cf a dict full of ...)?


The latter.


and so, returning to the matter of 'readability':

- the name "Borg" de-railed comprehension

- _instances:dict = {} implied the tracking of more than one

- should the class have been called either;

class SomethingSingleton():

or a Singleton() class defined, which is then sub-classed, ie

class Something( Singleton ):

in order to better communicate the coder's intent to the reader?

- from there, plenty of 'templates' exist for Singletons, so why do 
something quite different/alien to the reader?

(thus concurring with @Richard: "tricky" subverts 'readability')

- is it better to use a technique which 'we' will recognise, or to ask 
'us' to comprehend something 'new'?
(unless the 'new' is taking-advantage of a recent extension to the 
language, eg switch; to justify 'trail-blazing' a 
new/improved/replacement 'best practice')


- part of the 'tricky' seems to be an attempt to assess using an 
instance-attribute, rather than a class-attribute. If the :bool (or 
whichever) typing-annotation is added to a class-attribute (eg 
_instance), will the problem arise?


- does the sequence

_instance = False
...
if not cls._instance:
ie the explicit version
if cls._instance == False:

measure 'existence' or a value?

- does the sequence

_instance = None
...
if not cls._instance:
ie the explicit version:
if cls._instance is None:

measure 'existence' or identity?
(indeed, are they more-or-less the same concept?)

- do the *attr() functions test for 'existence'?

(that said, most of the code-examples I spotted, in reading-up on this, 
use either None or False - et tu Brute!)



Speaking of reading-up:

- am wondering where PEP 661 - Sentinel Values is 'going'?

- this article (https://python-patterns.guide/gang-of-four/singleton/) 
mentions that the original GoF Singleton Pattern preceded Python 
(particularly Python 3 classes). Also, that Python doesn't have 
complications present in C++. It further discusses "several drawbacks", 
which also champion 'readability' over 'trick' or 'sophistication'. I 
think you'll enjoy it!


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-09-30 Thread dn via Python-list

On 01/10/2023 11.25, Karsten Hilbert via Python-list wrote:

Am Sun, Oct 01, 2023 at 09:04:05AM +1300 schrieb dn via Python-list:


class WorkingSingleton(Borg):

def __init__(self):
print(self.__class__.__name__, ':')
try:
self.already_initialized
print('already initialized')
return

except AttributeError:
print('initializing')

self.already_initialized = True
self.special_value = 42



Where's the error in my thinking (or code) ?


What is your thinking?
Specifically, what is the purpose of testing self.already_initialized?


Apologies, my tending to use the "Socratic Method" with trainees (and 
avoiding any concept of personal-fault with others), means it can be 
difficult to tell if (personal*) introspection is being invited, or if I 
don't know the answer (and want to).


* personal cf Python code introspection (hah!)



The purpose is to check whether the singleton class has been
... initialized :-)

The line

self.already_initialized = True

is misleading as to the fact that it doesn't matter at all
what self.already_initialized is set to, as long as is
exists for the next time around.


Isn't it generally regarded as 'best practice' to declare (and define a value 
for) all
attributes in __init__()? (or equivalent) In which case, it will (presumably) 
be defined
as False; and the try-except reworded to an if-else.


I fail to see how that can differentiate between first-call
and subsequent call.


+1



Alternately, how about using hasattr()? eg

if hasattr( self.already_initialized, 'attribute_name' ):


That does work. I am using that idiom in other children of
Borg. But that's besides the point. I was wondering why it
does not work the same way with and without the type
annotation.


Annotations are for describing the attribute. In Python we don't have 
different instructions for declaring an object and defining it, eg


INTEGER COUNTER
COUNTER = 0

Thus, Python conflates both into the latter, ie

counter = 0
or
counter:int = 0

(both have the same effect in the Python Interpreter, the latter aims to 
improve documentation/reading/code-checking)


Typing defines (or rather labels) the object's type. Accordingly, occurs 
when the object is on the LHS (Left-hand Side) of an expression (which 
includes function-argument lists).


In this 'test for existence': in the case of WorkingSingleton(), the 
code-line is effectively only a RHS - see 'illegal' (below).


However, the annotation caused the code-line to be re-interpreted as 
some sort of LHS in FailingSingleton().
- as explained (@Mats) is understood as a 'typing expression' rather 
than 'Python code'.


Apologies: fear this a rather clumsy analysis - will welcome improvement...



 try:
 self.already_initialized

line is flagged by the assorted linters, etc, in my PyCharm as:

Statement seems to have no effect.


Well, the linter simply cannot see the purpose, which is
test-of-existence.




Question: is it a legal expression (without the typing)?

It borders on the illegal, I suppose, as the self-
introspection capabilities of the language are being
leveraged to achieve a legal purpose.



...and so we're addressing the important question: the try-test is for 
existence, cf for some value.


This can also be achieved by using the attribute in a legal expression, eg:

self.already_initialized == True


When introspecting code, if type-checkers cannot determine the purpose, 
is there likely to be a 'surprise factor' when a human reads it?

(that's Socratic! I already hold an opinion: right or wrong)


Might this remove the confusion (ref: @Mats):

self.already_initialized:bool == True

(not Socratic, don't know, haven't tested)




Which seems akin constructs for generating compatibility
between versions.


versions of ?



It seems the answer is being pointed to in Matts response.

It just mightily surprised me.


Me too!


I am slightly confused (OK, OK!) and probably because I don't have a 
good handle on "Borg" beyond knowing it is a Star Wars?Trek reference 
(apologies to the reader sucking-in his/her breath at such an utterance!).


What is the intent: a class where each instance is aware of every other 
instance - yet the word "Singleton" implies there's only one (cf a dict 
full of ...)?



Second move (also, slightly) off-topic:
I'm broadly in-favor of typing; additionally noting that trainees find 
it helpful whilst developing their code-reading skills. However, am not 
particularly zealous in my own code, particularly if the type-checker 
starts 'getting picky' with some co

Re: type annotation vs working code

2023-09-30 Thread dn via Python-list

On 01/10/2023 08.00, Karsten Hilbert via Python-list wrote:

A type annotation isn't supposed to change what code does,
or so I thought:

#
class Borg:
_instances:dict = {}

def __new__(cls, *args, **kargs):
# look up subclass instance cache
if Borg._instances.get(cls) is None:
Borg._instances[cls] = object.__new__(cls)
return Borg._instances[cls]


class WorkingSingleton(Borg):

def __init__(self):
print(self.__class__.__name__, ':')
try:
self.already_initialized
print('already initialized')
return

except AttributeError:
print('initializing')

self.already_initialized = True
self.special_value = 42


class FailingSingleton(Borg):

def __init__(self):
print(self.__class__.__name__, ':')
try:
self.already_initialized:bool
print('already initialized')
return

except AttributeError:
print('initializing')

self.already_initialized = True
self.special_value = 42

s = WorkingSingleton()
print(s.special_value)

s = FailingSingleton()
print(s.special_value)

#

Notice how Working* and Failing differ in the type annotation
of self.already_initialized only.

Output:

WorkingSingleton :
initializing
42

FailingSingleton :
already initialized <== 
Huh ?
Traceback (most recent call last):
  File 
"/home/ncq/Projekte/gm/git/gnumed/gnumed/client/testing/test-singleton.py", line 48, 
in 
print(s.special_value)
  ^^^
AttributeError: 'FailingSingleton' object has no attribute 
'special_value'


Where's the error in my thinking (or code) ?


What is your thinking?
Specifically, what is the purpose of testing self.already_initialized?

Isn't it generally regarded as 'best practice' to declare (and define a 
value for) all attributes in __init__()? (or equivalent) In which case, 
it will (presumably) be defined as False; and the try-except reworded to 
an if-else.


Alternately, how about using hasattr()? eg

if hasattr( self.already_initialized, 'attribute_name' ):
  # attribute is defined, etc


As the code current stands, the:

try:
self.already_initialized

line is flagged by the assorted linters, etc, in my PyCharm as:

Statement seems to have no effect.
Unresolved attribute reference 'already_initialized' for class 
'WorkingSingleton'.


but:

self.already_initialized:bool

passes without comment (see @Mats' response).


Question: is it a legal expression (without the typing)?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: path to python in venv

2023-09-27 Thread dn via Python-list


On 28/09/2023 09.32, Jon Ribbens via Python-list wrote:

On 2023-09-27, Larry Martell  wrote:

On Wed, Sep 27, 2023 at 12:42 PM Jon Ribbens via Python-list
 wrote:

On 2023-09-27, Larry Martell  wrote:

I was under the impression that in a venv the python used would be in
the venv's bin dir. But in my venvs I see this in the bin dirs:

lrwxrwxrwx 1 larrymartell larrymartell7 Sep 27 11:21 python -> python3
lrwxrwxrwx 1 larrymartell larrymartell   16 Sep 27 11:21 python3 ->
/usr/bin/python3

...

Not sure what this really means, nor how to get python to be in my venv.


WHy do you want python to be "in your venv"?


Isn't that the entire point of a venv? To have a completely self
contained env? So if someone messes with the system python it will not
break code running in the venv.


The main point of the venv is to isolate the installed packages,
rather than Python itself. I'm a bit surprised your symlinks are
as shown above though - mine link from python to python3.11 to
/usr/bin/python3.11, so it wouldn't change the version of python
used even if I installed a different system python version.



"venv — Creation of virtual environments" 
(https://docs.python.org/3/library/venv.html) starts by saying:


«The venv module supports creating lightweight “virtual environments”, 
each with their own independent set of Python packages installed in 
their site directories.»


but later expands this with: «Used to contain a specific Python 
interpreter...» even though the primary use-case treats the system 
interpreter as the "base" Python/environment.


Time for some reading and proving appropriate combinations of options?


Over the years there have been various proposals to enable multiple 
versions of Python to exist concurrently on a single machine, notably 
Python2 + Python3 - but am failing to recall any official docs on 
Python3.n + Python3.m; eg "PEP 554 – Multiple Interpreters in the 
Stdlib" (https://peps.python.org/pep-0554/).


That said there's plenty of articles on-line (which may/not feature 
venv*) such as "Multiple Python interpreters" 
(https://developer.fedoraproject.org/tech/languages/python/multiple-pythons.html)


* although the OP didn't mention an OpSys, one poster did mention 
Fedora-Linux...



NB some of this info may be dated - it is some time since conducted this 
investigation (and decided not to use venv - apologies!)


Am currently using PyCharm (courtesy of recent teams' conventions) and 
it eases both problems (which interpreter, and which 
development-environment/activation steps) but in automating 'the boring 
stuff' it will be interesting to see if in-future, I notice when the 
project is based upon an older system!
FYI 
https://www.jetbrains.com/help/pycharm/installing-uninstalling-and-reloading-interpreter-paths.html
(I'd be surprised if the other major tool-sets don't offer something 
similar)


Disclaimer: JetBrains sponsor our local PUG-meetings with a door-prize.

--
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Python Launcher Pops Up When Py-based App Is Running (Mac)

2023-09-18 Thread dn via Python-list

On 17/09/2023 13.20, James Greenham via Python-list wrote:

Hello,

On the face of it, the Python-Mac mailing list is largely inactive so I'm 
posting here since it looks like this one is livelier.



What happens when doGrab() is called from the REPL, after being 'fed' 
data you expect is valid? (per a unit-test)


What code-level debugging has been exercised?

Have you tried running the code in a debugger, in order to step into the 
(assumed) doGrab error?



Sadly, this code is so old as to have grown whiskers.
- are all the called-modules, eg webkit and the OpSys; still offering 
the appropriate interfaces, and continuing to behave in the expected 
fashion?

(anything relevant in those Release Notes?)
- in theory, Python 2 will still run. However, a reasonable proportion 
of today's Python-coders are unlikely to have ever used it.

(Sunsetting Python 2 https://www.python.org/doc/sunset-python-2/)
- were this code to be written using today's libraries, it is unlikely 
to look anything like this

(which may also be contributing to the dearth of replies)

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


ANN: Wed 20 Sep: Terminal-based user interfaces (TUIs) with ease using Textual

2023-09-07 Thread dn via Python-list

Rodrigo's back! Fresh from his successes at EuroPython...

You are invited to join the next virtual NZPUG Auckland Branch meeting 
(Wed 20 Sep, 1830~2030 local, ie 0630~0830 UTC)


Learn how to build powerful terminal-based user interfaces (TUIs) with 
ease using Textual - an open-source Python framework.


Through this tutorial, you'll learn how to use features like Textual's 
built-in widgets, reactive attributes, and message-passing system, to 
start developing a simple TODO app that runs directly in your terminal.



About Rodrigo Girão Serrão:

Rodrigo has presented to NZPUG Auckland Branch previously. He speaks 
frequently at various PyCons (Python Conferences) and other gatherings.


As well as Python, he has been playing with APL, C++, and more.

Combining programming and maths, he describes himself as a mathemagician.

Rodrigo has always been fascinated by problem solving and that is why he 
picked up programming – so that he could solve more problems.


He also loves sharing knowledge, and that is why he spends so much time 
writing articles in his blog, writing on Twitter, and giving workshops 
and courses.


During the week, Rodrigo can be found banging his head against the wall 
while trying to solve a Textual bug, as he works on Textual full-time.



To RSVP (to receive the meeting-URL) and for more detail: 
https://www.meetup.com/nzpug-auckland/events/295433884/



The Auckland branch of the New Zealand Python Users Group meets twice 
monthly. You're very welcome to attend online or in-person (as 
available). Meeting location-details or URL will be sent to those who RSVP.


We are a healthy mix of Python users. Students, academics, hobbyists, 
industry professionals, and many completely new to Python.


The 'room' opens at 1815 (local time) with an opportunity to network 
with colleagues. Formal start is 1830. Aiming to finish by 2030.


We are always keen to hear suggestions for meeting-topics, and to meet 
with folk who'd like to present or lead - eg a brief lightning talk, a 
practical coaching-session, a full lecture... Help is available if 
you've never done such a thing before!


We follow the NZPUG Code of Conduct to create an inclusive and friendly 
environment.


We express thanks to, and encourage you to investigate our sponsors: 
Catalyst Cloud, New Zealand Open Source Society, JetBrains, and IceHouse 
Ventures.



--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Co-op Group: Django web framework

2023-08-28 Thread dn via Python-list

Are you interested in learning Django?

Would like to improve your Django knowledge and skills?

Have you been picking-up Django piecemeal, and need to consolidate and 
clarify?


Do you know some Django and would like to acquire mentoring and coaching 
skills?



If so, please join us to form a Learning Django Co-op.
RSVP at https://www.meetup.com/nzpug-auckland/events/295727130/

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Context manager for database connection

2023-08-23 Thread dn via Python-list

On 24/08/2023 06.11, dn via Python-list wrote:

On 24/08/2023 03.41, Jason Friedman via Python-list wrote:

with Database() as mydb:
conn = mydb.get_connection()
cursor = conn.get_cursor()
cursor.execute("update table1 set x = 1 where y = 2")
cursor.close()
cursor = conn.get_cursor()
cursor.execute("update table2 set a = 1 where b = 2")
cursor.close()


import jaydebeapi as jdbc
class Database:
 database_connection = None

 def __init__(self, auto_commit: bool = False):
 self.database_connection = jdbc.connect(...)
 self.database_connection.jconn.setAutoCommit(auto_commit)

 def __enter__(self) -> jdbc.Connection:
 return self

 def __exit__(self, exception_type: Optional[Type[BaseException]],
  exception_value: Optional[BaseException],
  traceback: Optional[types.TracebackType]) -> bool:
 if exception_type:
 self.database_connection.rollback()
 else:
 self.database_connection.commit()
 self.database_connection.close()

 def get_connection(self) -> jdbc.Connection:
 return self.database_connection


Using a context-manager is a good idea: it ensures clean-up with/without 
an exception occurring. Accordingly, I (and may I presume, most) like 
the idea when working with life-cycle type resources, eg I/O. Absolutely 
nothing wrong with the idea!



However, the scope of a c-m is the with-block. If there are a number of 
'nested operations' to be performed (which could conceivably involve 
other c-ms, loops, or similar code-structures) the code could become 
harder to read and the length of the scope unwieldy.


An ease of management tactic is being able to see the start and end of a 
construct on the same page/screen. Such would 'limit' the length of a 
c-m's  scope.


Perhaps drawing an inappropriate parallel, but like a try-except block, 
there seems virtue in keeping a c-m's scope short, eg releasing 
resources such as a file opened for output, and some basic DBMS-es which 
don't offer multi-access.



Accordingly, why I stopped using a c-m for database work. NB YMMV!

There were two other reasons:
1 multiple databases
2 principles (and my shining virtue (?) )


1 came across a (statistics) situation where the client was using two 
DBMS-es. They'd used one for some time, but then preferred another. For 
their own reasons, they didn't migrate old data to the new DBMS. Thus, 
when performing certain analyses, the data-collection part of the script 
might have to utilise different DB 'sources'. In at least one case, 
comparing data through time, the routine needed to access both DBMS-es.

(oh what a tangled web we weave...)

2 another situation where the script may or may not actually have needed 
to access the DB. Odd? In which case, the 'expense' of the 'entry' and 
'exit' phases would never be rewarded.


Thus, 'inspired' to realise that had (long) been contravening SOLID's 
DSP advice?rule (Dependency Inversion Principle).



Accordingly, these days adopt something like the following (explaining 
it 'backwards' to aid comprehension in case you (gentle reader) have not 
come-across such thinking before - remember that word, "inversion"!)


- in the mainline, prior to processing, instantiate a database object

database = Database( credentials )

- assume the mainline calls a function which is the substance of the script:

def just_do_it( database_instance, other_args, ):
while "there's work to be done":
database.query( query, data, etc, )
# could be SELECT or UPDATE in and amongst the 'work'

- a basic outline of query() might be:

def query( self, sql, data, etc, ):
cursor = self.get_cursor()
cursor.execute( sql, data, ) # according to DB/connector, etc
# return query results

- a query can't happen without a "cursor", so either use an existing 
cursor, or create a fresh one:


def get_cursor( self ):
if not self._cursor:
connection = self.get_connection()
self._cursor = connection.cursor()
return self._cursor

NB assuming the DBMS has restrictions on cursors, I may have multiple 
connections with one cursor each, but in some situations it may be 
applicable to run multiple cursors through a single connection.


- a cursor can't exist without a "connection", so either ... :

def get_connection( self ):
if not self._connection:
self._connection = # connect to the DB
return self._connection

- to instantiate a DB-object in the first place, the class definition:

class Database:
def __init__(self):
self._connection = None
self._cursor = None

- and the one part of the exposition that's not 'backwards&#x

Re: Context manager for database connection

2023-08-23 Thread dn via Python-list

On 24/08/2023 03.41, Jason Friedman via Python-list wrote:

I want to be able to write code like this:

with Database() as mydb:
conn = mydb.get_connection()
cursor = conn.get_cursor()
cursor.execute("update table1 set x = 1 where y = 2")
cursor.close()
cursor = conn.get_cursor()
cursor.execute("update table2 set a = 1 where b = 2")
cursor.close()

I'd like for both statements to succeed and commit, or if either fails to
stop and for all to rollback.

Is what I have below correct?


import jaydebeapi as jdbc
class Database:
 database_connection = None

 def __init__(self, auto_commit: bool = False):
 self.database_connection = jdbc.connect(...)
 self.database_connection.jconn.setAutoCommit(auto_commit)

 def __enter__(self) -> jdbc.Connection:
 return self

 def __exit__(self, exception_type: Optional[Type[BaseException]],
  exception_value: Optional[BaseException],
  traceback: Optional[types.TracebackType]) -> bool:
 if exception_type:
 self.database_connection.rollback()
 else:
 self.database_connection.commit()
 self.database_connection.close()

 def get_connection(self) -> jdbc.Connection:
 return self.database_connection



Looking good!


Assuming this is the only DB-interaction, a context-manager seems 
appropriate. If the real use-case calls for more interactions, the cost 
of establishing and breaking DB-connections becomes a consideration. 
Alternately, the 'length'?'life' of the context-manager *might* 
complicate things.


Intriguing that given such a start, the code doesn't feature a 
context-manager for a query.



That two cursors are established is also a 'cost'. Could both queries 
utilise the same cursor?
(in which case, could consider adding to __init__() or __enter__(), and 
close in __exit__() )



Because the context-manager has been implemented as a class, there is no 
reason why one can't add more methods to that class (it doesn't need to 
be limited to the functional __enter__() and __exit__() methods!


Indeed there is already get_connection(). Why not also a query( self, 
sql-code ) method?



These might reduce the mainline-code to something like:

if __name__ == "__main__":
with Database() as mydb:
mydb.query( "update table1 set x = 1 where y = 2" )
mydb.query( "update table2 set a = 1 where b = 2" )
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Imports and dot-notation

2023-08-09 Thread dn via Python-list

On 09/08/2023 22.30, Oliver Schinagl via Python-list wrote:
...> Looking at a python projects code and repository layout, we see the

following directory structure.

/project/core
/project/components/module1
...
/project/components/moduleN
/projects/util

...> Some modules import other modules, and I see (at the very least) two

(kind of three?) different ways of doing so.

`from project.components.module1 import function1, function2 as func, 
CONST1, CONST2 as CONST`


or maybe even (which has as an advantage that it becomes clear which 
namespace something belongs to


`from project.components.module1 import function1, function2 as 
module1_function2, CONST1, CONST2 as MODULE1_CONST2`


but then it really just becomes personal preference, as the number of 
characters saved on typing is almost negative (due to having a more 
complex import).


but also the dot notation being used

`from project.components import module1`

where obviously the functions are invoked as `module1.function1` etc


Firstly, the path followed will depend upon the starting position!

Keep reading and you should come across a reference to 'hobgoblin of 
little minds'.


What should we be concentrating on/about? If 'naming' is a great (?the 
greatest) challenge of programming, surely remembering the names of 
classes, methods, functions, modules, etc; follows...
(and by implication, as you've illustrated, perhaps where they 
come-from), ie code is read more often than it is written, so think 
about comprehension rather than typing!



If one (one's team!) frequently uses a module, then a jargon may 
develop. For example:


import numpy as np
...
a = np.arange(6)

In which case, those au-fait with the jargon know that the "np." prefix 
tells them where "arange()" can be found - conversely, that if the IDE 
doesn't alert, that np/numpy must be (first) import-ed.


However, there is a cognitive-load to 'translate' "np" into "numpy". Not 
much, but then over-load is not a single thought but the combination of 
'everything'.


The second option (OP) is very (laboriously) clear in mapping the source 
of each function or constant. By way of comparison then, the code may 
now appear cluttered, because there's so much text to read. There would 
be less if an abbreviation were used.


The dev.tool in-use may also influence this decision. If hovering-over 
an identifier reveals source-information, what value the extra code? 
Intelligent completion also reduces relevance of 'number of characters 
saved on typing'.


Accordingly, give frequently-used functions/modules the abbreviation 
treatment -but only if YOU feel it right. Otherwise, use a longer-form 
to improve readability/comprehension.


THE answer will thus vary by library/package/module, by application, and 
by coder (jargon works best if 'all' use it/understand same).


Side note: Using "...import identifier, ..." does not save storage-space 
over "import module" (the whole module is imported regardless, IIRC), 
however it does form an "interface" and thus recommend leaning into the 
"Interface Segregation Principle", or as our InfoSec brethren would say 
'the principle of least privilege'. Accordingly, prefer "from ... import 
... as ...".


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Planning a Python / PyData conference

2023-08-08 Thread dn via Python-list

Hi Wilber,


On 09/08/2023 14.28, Wilber H via Python-list wrote:

Hi,

I would like to plan a Python / PyData conference in the country of the
Dominican Republic, and would like your feedback on how to best plan
for the conference.


Recommend making your request of the folks who organise EuroPython 
and/or PyConUS - and then same for smaller gatherings.


(would suggest to ours, but those folk are already over-loaded to be 
ready in a few weeks' time)


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Mtg ANN: Using computer vision AI to help protect the worlds rarest dolphin

2023-08-08 Thread dn via Python-list

Wed 16 Aug 2023, 1800~20:30 NZST (0600~0830 UTC, late-Tue in US)
Details and RSVP at https://www.meetup.com/nzpug-auckland/events/295091858/


Teaching a computer to see. How computer vision is helping to protect 
the world’s rarest dolphin and how you can train your own model.


Tane van der Boon will talk about the MAUI63 project, and then lead us 
through how to train and utilise a custom computer vision object 
detector. Essentially allowing our software to be able to see.


MAUI63 was given its name because when the venture began, there were 
only 63 Māui dolphins left in existence. Using drone technology and AI 
to collect and process visual data, the founders took action to collect 
data to help save the world’s rarest dolphin from extinction and 
influence future marine conservation efforts.


The MAUI63 team uses a customised drone to find and track the movement 
of dolphins, and enables individual dolphins to be identified through 
their fin markings. The information collected can then be used to inform 
better data driven decisions on how best to protect them.


Later, Tane will lead us through a smaller task to build our own image 
recognizer. (more details in due course...)



The Auckland Branch of the New Zealand Python Users' Group meet twice 
monthly. You're very welcome to attend online or in-person (as 
available). Meeting location-details or URL will be sent to those who RSVP.


We are a healthy mix of Python users. Students, academics, hobbyists, 
industry professionals, and many completely new to Python.


The "room" opens at 1800 (local time) with an opportunity to network 
with colleagues. Everything should be wrapped up by 2030.


We are always keen to hear suggestions for meeting-topics, and to meet 
with folk who'd like to present or lead - eg a brief lightning talk, a 
practical coaching-session, a full lecture... Help is available if 
you've never done such a thing before!


We follow the NZPUG Code of Conduct (https://python.nz/code-of-conduct) 
to create an inclusive and friendly environment.


We express thanks to, and encourage you to investigate, our sponsors: 
Catalyst Cloud, New Zealand Open Source Society, JetBrains, and IceHouse 
Ventures.


--
Regards =dn

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Where is the error?

2023-08-06 Thread dn via Python-list

On 07/08/2023 08.41, Peter J. Holzer via Python-list wrote:

Mostly, error messages got a lot better in Python 3.10, but this one had
me scratching my head for a few minutes.

...



The error message is now a lot better, of course, but the fact that it
points at the expression *before* the error completely threw me. The
underlined expression is clearly not missing a comma, nor is there an
error before that. My real program was a bit longer of course, so I
checked the lines before that to see if I forgot to close any
parentheses. Took me some time to notice the missing comma *after* the
underlined expression.

Is this "clairvoyant" behaviour a side-effect of the new parser or was
that a deliberate decision?


Found myself chuckling at this - not to be unkind, but because can 
easily imagine such confusion on my own part.


The issue of unhelpful error messages or information aimed at a similar 
but different context, has been the story of our lives. Advice to 
trainees has always been to cast-about looking for the error - rather 
than taking the line-number as a precise location. Have made a note to 
avoid advising folk to work 'backwards'!


Meantime (back at the ranch?), haven't experienced this. Using an IDE 
means all such stuff is reported, as one types, through highlights and 
squiggly lines (which should(?) be considered and cleared - before 
pressing the GO-button).


In this case, the PyCharm* editor adds red-squiggles where the commas 
should have been. Hovering the cursor over a squiggle, the IDE reports 
"',' expected"! Its PythonConsole behaves similarly (without offering a 
'hover'). Plus, even after the closing brace, it continues to assume a 
multi-line compound-statement (and thus won't execute, per expected REPL 
behavior).



Way-back (grey-beard time!) when we submitted card-decks of code to be 
compiled over-night, one idea to avoid expensive, trivial errors/eras; 
was that spelling-checkers should be built-in to compilers, eg to 
auto-magically correct typos, eg


AFF 1 TO TOTAL

instead of:

ADD 1 TO TOTAL

These days, we can look at code from two or more years ago, 'produced' 
by ChatGPT (et al), aka "The Stochastic Parrot". There is some thought 
that artificial 'intelligence' will one-day be able to do the coding for 
us/predict what is required/act as a crystal ball...


Speaking of which, and just because I could, here's what Chat-GPT had to 
say when I asked "what's wrong with ...":


«The issue in the given Python code is that you're missing commas 
between the key-value pairs in the dictionary. Commas are required to 
separate different key-value pairs within a dictionary. Here's the 
corrected version of the code:

...
»

Question: If a Chat-AI is built into the IDE (I stripped such out from 
mine), does it take-over error reporting and diagnosis (and offer the 
option of replacing with its 'corrected version'?) - rather than 
requiring an extra copy-paste step, per above?

(and need for my assumption of where the error is located)


Hope you've exerted copyright over the "clairvoyant" description!


* JetBrains kindly sponsor our PUG with a monthly door-prize.
--
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: isinstance()

2023-08-04 Thread dn via Python-list

On 05/08/2023 11.18, Chris Angelico via Python-list wrote:

On Sat, 5 Aug 2023 at 09:08, dn via Python-list  wrote:


On 03/08/2023 11.38, Jon Ribbens via Python-list wrote:

On 2023-08-02, dn  wrote:

Can you please explain why a multi-part second-argument must be a tuple
and not any other form of collection-type?


The following comment may hold a clue:

  if (PyTuple_Check(cls)) {
  /* Not a general sequence -- that opens up the road to
 recursion and stack overflow. */

https://github.com/python/cpython/blob/main/Objects/abstract.c#L2684

Plus an almost total lack of demand for change I should think.


Thanks for the reference!


Am not proposing a change (have learned 'the rule' and accepted
life-as-it-is), but was curious about the restriction: why not any
(reasonable sequence)?


There are quite a few places where the only option is a tuple.


"spam".startswith(["sp", "h"])

Traceback (most recent call last):
   File "", line 1, in 
TypeError: startswith first arg must be str or a tuple of str, not list

try: 1/0

... except [ValueError, IndexError]: pass
...
Traceback (most recent call last):
   File "", line 1, in 
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
   File "", line 2, in 
TypeError: catching classes that do not inherit from BaseException is
not allowed

It simplifies a lot of checks. Either it's a tuple or it's a single
thing. A *lot* of values are iterable, but only tuples are tuples.

As the C comment notes, this also means you don't have to worry about
recursion; otherwise, even core language features like exception
handling would have to iterate over a thing while ensuring that they
don't get stuck in self-referential objects. (Incidentally, it seems
that exception handling doesn't bother with recursion *at all*, and
won't catch "(a, (b, c))" - but even if recursion is handled, it can't
go infinite, short of some serious messing around in ctypes or the C
API.)

Yes. Thanks Chris!

The idea that such 'lists' be immutable (even, hashable), and therefore 
a tuple, makes a certain amount of sense, and @Cameron mentioned 
'frugality'.



My limitation is thinking only at the Python level (which as @Jon 
pointed-out, is only part of the story).


Faced with a situation where an argument may be a scalar-value or an 
iterable, I'll presume the latter, eg throw it straight into a for-loop. 
If that fails (because the argument is a scalar), use try-except to 
re-route the logic. Alternately, in an OOP situation, utilise 
polymorphism so that the 'scalar' and 'iterable' instances both include 
the appropriate method[name]. Accordingly, as long as the argument is an 
iterable (includes an __iter__() method), the actual type/class is 
more-or-less irrelevant.



However, as observed earlier - and with these additions, having learned 
the 'rule', ie use a tuple; the brain is still pondering, but have 
shrugged-shoulders and carried-on regardless...


--
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: isinstance()

2023-08-04 Thread dn via Python-list

On 03/08/2023 11.38, Jon Ribbens via Python-list wrote:

On 2023-08-02, dn  wrote:

Can you please explain why a multi-part second-argument must be a tuple
and not any other form of collection-type?


The following comment may hold a clue:

 if (PyTuple_Check(cls)) {
 /* Not a general sequence -- that opens up the road to
recursion and stack overflow. */

https://github.com/python/cpython/blob/main/Objects/abstract.c#L2684

Plus an almost total lack of demand for change I should think.


Thanks for the reference!


Am not proposing a change (have learned 'the rule' and accepted 
life-as-it-is), but was curious about the restriction: why not any 
(reasonable sequence)?



Such pondering continues in my subversive mind, given such thoughts as:

- "we're all adults here"
(eg frequent justification when arguing about Python not having "private 
attributes" per-se).

So, if we introduce a complexity, on our own heads be it!
(hardly likely given that all we are likely to attempt is the 
application of a simple and short 'list' of [un]acceptable types).
NB understood that the quoted-code is applied in many and other 'scalar 
or tuple' situations.


- Python happily enables recursion, which "opens up the road to 
recursion and stack overflow.".

So, why install a 'nanny' to save us from ourselves here?
Again: seems on-the-surface that such 'lists' (at the code-line level) 
will be mono-dimensional 99.9% of the time.



NB having said that, the underlying mechanism *is* multi-dimensional: 
"direct, indirect, or virtual) subclass thereof" 
(https://docs.python.org/3/library/functions.html#isinstance)


Further: the 'rules' say: "classinfo is a tuple of type objects (or 
recursively, other such tuples)". Thus, can write:


>>> target_object = ...
>>> inner_tuple = float, complex
>>> inner_tuple
(, )
>>> isinstance( target_object, ( str, inner_tuple, int, ), )
False

I can't say I've ever used such construction in-the-wild - either 
defining and then using an "inner_tuple", or even nesting. YMMV!



Any thoughts?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to find the full class name for a frame

2023-08-03 Thread dn via Python-list

On 04/08/2023 15.34, Jason Friedman via Python-list wrote:

import inspect

def my_example(arg1, arg2):
print(inspect.stack()[0][3])
my_frame = inspect.currentframe()
args,_,_,values = inspect.getargvalues(my_frame)
args_rendered = [f"{x}: {values[x]}" for x in args]
print(args_rendered)

my_example("a", 1)


The above "works" in the sense it prints what I want, namely the method
name (my_example) and the arguments it was called with.


The above didn't 'work' - please copy-paste and ensure that the 
email-client is respecting indentation.




My question is: let's say I wanted to add a type hint for my_frame.

my_frame: some_class_name = inspect.currentframe()

What would I put for some_class_name?
"frame" (without quotations) is not recognized,
Nor is inspect.frame.


We know Python code is executed in an execution frame. 
(https://docs.python.org/3/reference/executionmodel.html?highlight=frame)


We are told "Frame objects Frame objects represent execution frames." 
(https://docs.python.org/3/reference/datamodel.html?highlight=frame). 
The word "represent" conflicts with the idea of "are".


'Under the hood' inspect calls sys._current_frames() 
(https://docs.python.org/3/library/sys.html?highlight=frame). That code is:


def _getframe(*args, **kwargs): # real signature unknown
"""
Return a frame object from the call stack.

If optional integer depth is given, return the frame object that many
calls below the top of the stack.  If that is deeper than the call
stack, ValueError is raised.  The default for depth is zero, returning
the frame at the top of the call stack.

This function should be used for internal and specialized purposes
only.
"""
pass

Which rather suggests that if the sys library doesn't know the 
signature, then neither typing nor we mere-mortals are going to do so, 
either.



Theory: the concept of a frame does not really exist at the Python-level 
(remember "represents"). Frames (must) exist at the C-level 
(https://docs.python.org/3/c-api/frame.html?highlight=frame#c.PyFrameObject) 
of the virtual-machine - where typing is not a 'thing'.



It's an interesting question. Perhaps a better mind than mine can give a 
better answer?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


isinstance()

2023-08-02 Thread dn via Python-list
Can you please explain why a multi-part second-argument must be a tuple 
and not any other form of collection-type?



The signature is: isinstance(object, classinfo)
leading to "classinfo" of:

1/ a single class/type, eg int
2/ a tuple of same, eg ( int, str, )
3/ a union type, eg int | str (v3.10+)

A question was asked about this at last night's PUG-meeting. The person 
was using the union option, but from Python v3.8. Sorting that out, he 
replaced the union with a list. No-go! Before correcting to a tuple...


Why does the second argument need to be a tuple, given that any series 
of non-keyword arguments is a tuple; and that such a tuple will still 
need to be delimited by parentheses. In other words, other forms of 
delimiter/collection, eg list and set; being a series of 
elements/members would seem no different.


Yes, the underlying C operation appears to only accept a single argument 
(am not C-soned, mea culpa!).


There is some discussion about hashability, but isn't it coincidental 
rather than constructive? (again, maybe I've not understood...)


Enquiring minds want to know...


Web.Refs:
https://docs.python.org/3/library/functions.html?highlight=isinstance#isinstance
https://docs.python.org/3/c-api/object.html?highlight=isinstance#c.PyObject_IsInstance
https://docs.python.org/3/reference/datamodel.html?highlight=isinstance

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Hybrid meeting ANN: Using properties and descriptors

2023-07-11 Thread dn via Python-list
This month's meeting (Wed 19 July, 1800 for 1830 NZST = 0600/0630 UTC) 
will cover more-advanced OOP Python skills. You will be most-welcome to 
join us...



"Using properties and descriptors" will look at a series of 
code-examples exploring problems and how these constructs offer 
solutions. The presentations are in lecture-style. If there's time (or 
for later study), some coding workshops will be suggested.


Prerequisite knowledge or experience for "Properties":
Object-Oriented Programming (in Python), coding custom-classes, using 
available decorators, some experience in data organisation/design, 
PEP-008 and coding styles, and reading type-hints.


Prerequisite knowledge or experience for "Descriptors":
"Properties" topic in this series, coding custom-classes with 'magic 
methods', implementing inheritance and composition, design-experience in 
data organisation, Object-Oriented Design, decent understanding of OOP 
philosophy.


Hints: A lab-/log-book will be useful for taking notes. A headset will 
ease asking questions, answering questions, and discussion. Python IDE 
ready for coding.


Two choices for attendance: online or in-person (Parnell, Auckland). 
Please RSVP to book-in and receive access information:-


- Remote attendance RSVP: 
https://www.meetup.com/nzpug-auckland/events/njdjssyfckbzb/

- In-person RSVP to https://www.meetup.com/nzpug-auckland/events/294745326/

You are cordially invited to join us!
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: my excel file is not updated to add new data

2023-06-26 Thread dn via Python-list

Marc,

Apologies for writing in English (the language of this Discussion List). 
I have attempted to keep the code in French...


Thanks for this question. If it's OK with you, I would like to use it as 
an example-problem (and 'solution') challenge for some future Python 
Users' Group meeting (suitably translated, etc)...



On 27/06/2023 05.46, small marcc via Python-list wrote:


This code creates the path to the Excel file where the data will be written. It 
checks if the file already exists, and if so, reads the existing data into a 
DataFrame. Otherwise, it creates a new empty DataFrame. Then it concatenates 
the existing data with the new data and writes the result to the Excel file. 
Finally, it displays a message that the backup was successful and closes the 
information window.

I do not understand why it does not work, the new data is not displayed in 
excel when I am in python tkinter, my data in python must be displayed in excel.
I use the following code to write data to an excel file using pandas:

please help meHowever, when I run this code, the new data is not showing in the 
excel file. I don't understand why this isn't working. Can you help me solve 
this problem?


Is this a Python problem, or a problem with the way the solution has 
been coded?


There are several steps in the solution-description. It is troubling (to 
both of us) that you are unable to locate the source of the error. Why? 
Because it is not noticed until the final stage "new data is not displayed"!


NB am ignoring that the line defining "df" and everything thereafter, 
appears to be incorrectly indented - when viewed in my email-client. 
That said, the sequence of events seems muddled.



Please review the code. Compare it to the verbal/English-language 
description of the solution. Can each sentence in the solution be easily 
identified in the code?


Words like "and", "otherwise", "then", and "finally" indicate that there 
are multiple steps in the process. Let's split the separate sentences 
and phrases:


- creates the path to the Excel file where the data will be written
- checks if the file already exists
[establish DataFrame]
  - if so, reads the existing data into a DataFrame
  - Otherwise, it creates a new empty DataFrame
- concatenates the existing data with the new data
- writes the result to the Excel file
- displays a message that the backup was successful
- closes the information window.

NB addition of a task-label summarising the two DataFrame alternative 
situations.



Now, we can outline the Python code by writing a bunch of function 
definitions:


def create_data_path():
def check_for_file():
def establish_data_frame():
  def read_existing_data():
  def create_new_data_frame():
def accept_new_data():
def save_to_file():
def report():
def terminate():

NB my IDE would grumble and complain if I did this 'for real'. In a 'new 
code' situation, you may like to add a pass-statement inside each, and 
vertical-spacing to make the distracting-complaints 'go away'. 
Alternately and assuming the function-name doesn't say it all, add a 
docstring (you're going to add one anyway, right?) and expand upon the 
function-name with some explanation of what the function will do. In 
this situation, you could add the existing code.


NBB the two sub-tasks have been indented here for continuity of flow. 
They may/may not be nested within establish_data_frame() when you detail 
the content of each function - not important to this outline.


NBBB I've quickly drafted function-names for the sake of this 
discussion. I find it easier to name things when it is time to use them 
(in this case, call the function). Fortunately, a competent IDE will 
facilitate the refactoring of names ("symbols"). Yes, doing it that way 
costs (me) little extra effort - but it saves straining my brain 
up-front. That said, investing time in 'designing' a good name, will 
also tend to clarify and sharpen one's thinking. So, apparently I follow 
both paths... YMMV!



Now that the solution has been outlined, one can consider what output 
you expect from each function, what input it will require to produce 
that, and the transformation in-between. For example:


def create_data_path( nom_fichier ):
* copy existing code into here
return chemin_fichier_excel

(pausing at the one function, for now...)

[for non-French speakers:
nom_fichier = file_name
chemin_fichier_excel = data path including file-name
]


How has this design-process improved things?

1 clearer thinking: we have a simple and more straightforward idea of 
what should happen
2 "separation of concerns": each function does one job (and should do it 
well!)
3 testability: we can now ensure that the (each) function performs 
correctly (in isolation)
4 the problem of locating the source of an error is simplified (in fact, 
the "testability" advantage may solve this problem - or in a new-design 
situation, avoid it*)



Testing the function is carried-out by calling the function

Re: Python Issue

2023-06-21 Thread dn via Python-list

On 22/06/2023 03.28, Pickle Pork via Python-list wrote:

Python is unable to open. Exit Code: 1


This is not good.

Please give some useful information:
- from where did you download Python?
- which operating system?
- how do you "open" Python?
etc.

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Should NoneType be iterable?

2023-06-19 Thread dn via Python-list

On 20/06/2023 06.12, Neal Becker via Python-list wrote:

On Mon, Jun 19, 2023 at 12:42 PM Chris Angelico via Python-list <
python-list@python.org> wrote:


On Tue, 20 Jun 2023 at 02:37, Peter Bona via Python-list
 wrote:


Hi

I am wondering if there has been any discussion why NoneType  is not

iterable My feeling is that it should be.

Sometimes I am using API calls which return None.
If there is a return value (which is iterable) I am using a for loop to

iterate.


Now I am getting 'TypeError: 'NoneType' object is not iterable'.

(Examples are taken from here

https://rollbar.com/blog/python-typeerror-nonetype-object-is-not-iterable/
)

Example 1:
mylist = None
for x in mylist:
 print(x)  <== will raise TypeError: 'NoneType' object is not iterable
Solution: extra If statement
if mylist is not None:
 for x in mylist:
 print(x)


I think Python should handle this case gracefully: if a code would

iterate over None: it should not run any step. but proceed the next
statement.


Has this been discussed or proposed?



Try this instead:

for x in mylist or ():

Now a None list will skip iteration entirely, allowing you to get the
effect you want :)

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list


I prefer iteration of None to be an error, as in my usage it usually
indicates a mistake that I'd want to catch


Agreed!

A better approach is that the API return (perhaps a tuple of) both 
"status" and "return_value", rather than overloading the latter.


That said, apparently the OP use-case is for when there is no interest 
in status/catch, eg where a 'nothing' answer is THE answer.


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   >