Re: Two aces up Python's sleeve (Posting On Python-List Prohibited)

2024-11-08 Thread Thomas Passin via Python-list

On 11/8/2024 2:09 PM, dn via Python-list wrote:

On 8/11/24 14:40, Mild Shock via Python-list wrote:

Well you can use your Browser, since
JavaScript understand post and pre increment:


Question: are we talking Python or JavaScript?



So we have x ++ equals in Python:


Trying to find a word-for-word translation serves as badly in computer- 
programming languages as it does in human spoken-languages. Learn how to 
adapt and embrace the differences...




 x + = 1
 x - 1


The above probably only 'works' (the way you expect) in the REPL.



But I don't know how to combine an
assignment and an expression into one
expession. In JavaScript one can use


Again!

"Everything should be made as simple as possible, but no simpler."

Check out "The Zen of Python" and PEP-0008 for Python idioms.



the comma:

 > x = 5
5
 > y = (x += 1, x - 1)
5
 > x = 5
5
 > y = (x += 1, x)
6

But in Python the comma would create a tuple.


Exactly, just as driving on the left side of the road will be fine in 
some countries but cause a crash in others. Learn the local rules FIRST!



The 'walrus operator' could be applied:

 >>> x = 5
 >>> y = (x := x + 1); x
6
 >>> x, y
(6, 6)

However, if such were submitted for Code Review, unhappiness would result.


Was the question re-phrased to: how to ... in Python, we'd end-up with 
something more like this:


 >>> x = 5  # define
 >>> x += 1  # increment
 >>> y = x  # alias
 >>> x, y
(6, 6)


Or, still Pythonic but simpler:

>>> x = 5
>>> y = x = x + 1
>>> x, y
(6, 6)

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


Re: How to check whether audio bytes contain empty noise or actual voice/signal?

2024-10-26 Thread Thomas Passin via Python-list

On 10/25/2024 12:25 PM, marc nicole via Python-list wrote:

Hello Python fellows,

I hope this question is not very far from the main topic of this list, but
I have a hard time finding a way to check whether audio data samples are
containing empty noise or actual significant voice/noise.

I am using PyAudio to collect the sound through my PC mic as follows:

FRAMES_PER_BUFFER = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 48000
RECORD_SECONDS = 2import pyaudio
audio = pyaudio.PyAudio()
stream = audio.open(format=FORMAT,
 channels=CHANNELS,
 rate=RATE,
 input=True,
 frames_per_buffer=FRAMES_PER_BUFFER,
 input_device_index=2)
data = stream.read(FRAMES_PER_BUFFER)


I want to know whether or not data contains voice signals or empty sound,
To note that the variable always contains bytes (empty or sound) if I print
it.

Is there an straightforward "easy way" to check whether data is filled with
empty noise or that somebody has made noise/spoke?


It's not always so easy.  The Fast Fourier Transform will be your 
friend. The most straightforward way would be to do an autocorrelation 
on the recorded interval, possibly with some pre-filtering to enhance 
the typical vocal frequency range.  If the data is only noise, the 
autocorrelation will show a large signal at point 0 and only small, 
obviously noisy numbers everywhere else. There are practical aspects 
that make things less clear.  For example, voices tend to be spiky and 
erratic so you need to use small intervals to have a better chance of 
getting an interval with a good S/N ratio, but small intervals will have 
a lower signal to noise ratio.


Human speech is produced with various statistical regularities and these 
can sometimes be detected with various means, including the autocorrelation.


You also will need to test-record your entire signal chain because it 
might be producing artifacts that could fool some tests.  And background 
sounds could fool some tests as well.


Here are some Python libraries that could be very helpful:

librosa (I have not worked with this but it sounds right on target);
scipy.signal (I have used scypi but not specifically scipy.signal);
python-speech-features (another I haven't used);
https://python-speech-features.readthedocs.io/en/latest/

Other people will know of others.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Correct syntax for pathological re.search()

2024-10-12 Thread Thomas Passin via Python-list

On 10/11/2024 8:37 PM, MRAB via Python-list wrote:

On 2024-10-11 22:13, AVI GROSS via Python-list wrote:
Is there some utility function out there that can be called to show 
what the
regular expression you typed in will look like by the time it is ready 
to be

used?

Obviously, life is not that simple as it can go through multiple 
layers with

each dealing with a layer of backslashes.

But for simple cases, ...


Yes. It's called 'print'. :-)


There is section in the Python docs about this backslash subject.  It's 
titled "The Backslash Plague" in


https://docs.python.org/3/howto/regex.html

You can also inspect the compiled expression to see what string it 
received after all the escaping:



import re

re_string = '\\w+sub'
re_pattern = re.compile(re_string)

# Should look as if we had used r'\w+\\sub'
print(re_pattern.pattern)

\w+\\sub



-Original Message-
From: Python-list bounces+avi.e.gross=gmail@python.org> On

Behalf Of Gilmeh Serda via Python-list
Sent: Friday, October 11, 2024 10:44 AM
To: python-list@python.org
Subject: Re: Correct syntax for pathological re.search()

On Mon, 7 Oct 2024 08:35:32 -0500, Michael F. Stemper wrote:


I'm trying to discard lines that include the string "\sout{" (which is
TeX, for those who are curious. I have tried:
   if not re.search("\sout{", line): if not re.search("\sout\{", line):
   if not re.search("\\sout{", line): if not re.search("\\sout\{",
   line):

But the lines with that string keep coming through. What is the right
syntax to properly escape the backslash and the left curly bracket?


$ python
Python 3.12.6 (main, Sep  8 2024, 13:18:56) [GCC 14.2.1 20240805] on 
linux

Type "help", "copyright", "credits" or "license" for more information.

import re
s = r"testing \sout{WHADDEVVA}"
re.search(r"\\sout{", s)



You want a literal backslash, hence, you need to escape everything.

It is not enough to escape the "\s" as "\\s", because that only takes 
care

of Python's demands for escaping "\". You also need to escape the "\" for
the RegEx as well, or it will read it like it means "\s", which is the
RegEx for a space character and therefore your search doesn't match,
because it reads it like you want to search for " out{".

Therefore, you need to escape it either as per my example, or by using
four "\" and no "r" in front of the first quote, which also works:


re.search("sout{", s)



You don't need to escape the curly braces. We call them "seagull wings"
where I live.





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


Re: Correct syntax for pathological re.search()

2024-10-12 Thread Thomas Passin via Python-list

On 10/12/2024 6:59 AM, Peter J. Holzer via Python-list wrote:

On 2024-10-11 17:13:07 -0400, AVI GROSS via Python-list wrote:

Is there some utility function out there that can be called to show what the
regular expression you typed in will look like by the time it is ready to be
used?


I assume that by "ready to be used" you mean the compiled form?

No, there doesn't seem to be a way to dump that. You can

 p = re.compile("sout{")
 print(p.pattern)

but that just prints the input string, which you could do without
compiling it first.


It prints the escaped version, so you can see if you escaped the string 
as you intended. In this case, the print will display '\\sout{'.  That's 
worth something.




But - without having looked at the implementation - it's far from clear
that the compiled form would be useful to the user. It's probably some
kind of state machine, and a large table of state transitions isn't very
readable.

There are a number of websites which visualize regular expressions.
Those are probably better for debugging a regular expression than
anything the re module could reasonably produce (although with the
caveat that such a web site would use a different implementation and
therefore might produce different results).

 hp




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


Re: Best Practice Virtual Environment

2024-10-05 Thread Thomas Passin via Python-list

On 10/5/2024 4:27 PM, Ulrich Goebel via Python-list wrote:

Hi,

I learned to use virtual environments where ever possible, and I learned to pip 
install the required packages there.

That works quite nice at home. Now I come to deploy a Python script on a debian 
linux server, making it usable for a couple of users there.

Debian (or even Python3 itself) doesn't allow to pip install required packages 
system wide, so I have to use virtual environments even there. But is it right, 
that I have to do that for every single user?

Can someone give me a hint to find an howto for that?


One alternative is to install a different version of Python without 
replacing the system's version. For example, if the system uses Python 
3.11, install Python 3.12.  That way there is no risk of breaking system 
operation, and you can install what you like where you like.

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


Re: Help with Streaming and Chunk Processing for Large JSON Data (60 GB) from Kenna API

2024-09-30 Thread Thomas Passin via Python-list

On 9/30/2024 11:30 AM, Barry via Python-list wrote:




On 30 Sep 2024, at 06:52, Abdur-Rahmaan Janhangeer via Python-list 
 wrote:


import polars as pl
pl.read_json("file.json")




This is not going to work unless the computer has a lot more the 60GiB of RAM.

As later suggested a streaming parser is required.


There is also the json-stream library, on PyPi at

https://pypi.org/project/json-stream/


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


Re: Help with Streaming and Chunk Processing for Large JSON Data (60 GB) from Kenna API

2024-09-30 Thread Thomas Passin via Python-list

On 9/30/2024 1:00 PM, Chris Angelico via Python-list wrote:

On Tue, 1 Oct 2024 at 02:20, Thomas Passin via Python-list
 wrote:


On 9/30/2024 11:30 AM, Barry via Python-list wrote:




On 30 Sep 2024, at 06:52, Abdur-Rahmaan Janhangeer via Python-list 
 wrote:


import polars as pl
pl.read_json("file.json")




This is not going to work unless the computer has a lot more the 60GiB of RAM.

As later suggested a streaming parser is required.


Streaming won't work because the file is gzipped.  You have to receive
the whole thing before you can unzip it. Once unzipped it will be even
larger, and all in memory.


Streaming gzip is perfectly possible. You may be thinking of PKZip
which has its EOCD at the end of the file (although it may still be
possible to stream-decompress if you work at it).

ChrisA


You're right, that's what I was thinking of.

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


Re: Help with Streaming and Chunk Processing for Large JSON Data (60 GB) from Kenna API

2024-09-30 Thread Thomas Passin via Python-list

On 9/30/2024 11:30 AM, Barry via Python-list wrote:




On 30 Sep 2024, at 06:52, Abdur-Rahmaan Janhangeer via Python-list 
 wrote:


import polars as pl
pl.read_json("file.json")




This is not going to work unless the computer has a lot more the 60GiB of RAM.

As later suggested a streaming parser is required.


Streaming won't work because the file is gzipped.  You have to receive 
the whole thing before you can unzip it. Once unzipped it will be even 
larger, and all in memory.

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


Re: Python 3.8 or later on Debian?

2024-09-18 Thread Thomas Passin via Python-list

On 9/18/2024 10:49 AM, 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...


My Debian 12 VM has python 3.11.  You must have a very old version of 
Debian. On some VMs (not Debian, I think) I have had other Python 
versions alongside of the system's, e.g., 3.11 and 3.12. I didn't 
compile them myself. You will have to search for a repository with the 
right package.  But upgrade your system first!

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


Re: Sanitise user input for a script

2024-08-30 Thread Thomas Passin via Python-list

On 8/30/2024 3:18 PM, Simon Connah via Python-list wrote:

I need to write a script that will take some user input (supplied on a website) 
and then execute a Python script on a host via SSH. I'm curious what the best 
options are for protecting against malicious input in much the smae way as you 
sanitise SQL to protect against SQL injections.


You should never, never, never "sanitize" SQL. Use prepared statements 
instead.


What kind of user input do you expect to get that would need to be 
"sanitized"? How are you going to use it such that malicious input might 
cause trouble?  I hope you aren't planning to exec() it.  Are you 
expecting a user to send in a script and your server will execute it? 
Better read up on sandboxing, then.


If you won't be exec()ing a script, then you can consider creating an 
API where each method of the API can only do limited things, and only 
with certain parameters not all of all them. The SSH message can include 
the name of the method to use.


And follow what Peter Holzer wrote.  Don't forget that quoting practices 
are not the same between Windows and Linux.




I could do it either on the website itself or by doing it on the host machine.

I'm thinking of using argparse but I'm aware it does not offer any protection 
itself.

If someone has any suggestions I'd appreciated it. If you need more information 
then please let me know.

Simon.




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


Re: Script stops running with no error

2024-08-28 Thread Thomas Passin via Python-list

On 8/28/2024 8:07 PM, dn via Python-list wrote:

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.


To give more detail:

import json
from pprint import pprint

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

data_dict = json.loads(DATA)
pprint(data_dict)

Easy. If you have a really big file it can be fearfully slow so it may 
or may not be a good approach for this problem.


Or you could parse out the data with JSONpath (which I have never used 
but it's the right kind of approach):


https://pypi.org/project/jsonpath-ng/

Another possibility: JMESPath:

https://python.land/data-processing/working-with-json/jmespath

These kind of approaches also handle the parsing for you and help in 
constructing queries.


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

Re: Script stops running with no error

2024-08-28 Thread Thomas Passin via Python-list

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

What's happening?

I run the script and, maybe I don't know shit from shinola, but it
appears I composed it properly. I wrote the script to do the above.
The wiktionary json file denotes a list with this character # and
sublists as ## but numbers them

On Wiktionary, the definitions are denoted like:

1. blablabla
 1. blablabla
 2. blablablablabla
2. balbalbla
3. blablabla
1. blablabla


I wrote my script to alter it so that the sublist are letters

1. blablabla
a. blablabla
b. blablabla
2. blablabla and so on
/snip

At this point, the script stops after it assesses the first line_counter
and sub_counter. The code is below, please tell me which stupid mistake
I made (I'm sure it's simple).

Am I making a bad approach? Is there an easier method of parsing json
than the way I'm doing it? I'm all ears.

Be kind, i'm really new at python. Environment is emacs.

import requests
import re

search_url = 'https://api.wikimedia.org/core/v1/wiktionary/en/search/page'
search_query = 'table'
parameters = {'q': search_query}

response = requests.get(search_url, params=parameters)
data = response.json()

page_id = None

if 'pages' in data:
 for page in data['pages']:
 title = page.get('title', '').lower()
 if title == search_query.lower():
 page_id = page.get('id')
 break

if page_id:
 content_url =
 f'https://api.wikimedia.org/core/v1/wiktionary/en/page/
 {search_query}'
 response = requests.get(content_url)
 page_data = response.json()
 if 'source' in page_data:
 content = page_data['source']
 cases = {'noun': r'\{en-noun\}(.*?)(?=\{|\Z)',
  'verb': r'\{en-verb\}(.*?)(?=\{|\Z)',
  'adjective': r'\{en-adj\}(.*?)(?=\{|\Z)',
  'adverb': r'\{en-adv\}(.*?)(?=\{|\Z)',
  'preposition': r'\{en-prep\}(.*?)(?=\{|\Z)',
  'conjunction': r'\{en-con\}(.*?)(?=\{|\Z)',
  'interjection': r'\{en-intj\}(.*?)(?=\{|\Z)',
  'determiner': r'\{en-det\}(.*?)(?=\{|\Z)',
  'pronoun': r'\{en-pron\}(.*?)(?=\{|\Z)'
  #make sure there aren't more word types
 }

 def clean_definition(text):
 text = re.sub(r'\[\[(.*?)\]\]', r'\1', text)
 text = text.lstrip('#').strip()
 return text
 
 print(f"\n*** Definition for {search_query} ***")

 for word_type, pattern in cases.items():
 match = re.search(pattern, content, re.DOTALL)
 if match:
 lines = [line.strip() for line in
 match.group(1).split('\n')
 if line.strip()]
 definition = []
 main_counter = 0
 sub_counter = 'a'

 for line in lines:
 if line.startswith('##*') or line.startswith('##:'):
 continue

 if line.startswith('# ') or line.startswith('#\t'):
 main_counter += 1
 sub_counter = 'a'
 cleaned_line = clean_definition(line)
 definition.append(f"{main_counter}. {cleaned_line}")
 elif line.startswith('##'):
 cleaned_line = clean_definition(line)
 definition.append(f"   {sub_counter}. {cleaned_line}")
 sub_counter = chr(ord(sub_counter) + 1)

 if definition:
 print(f"\n{word_type.capitalize()}\n")
 print("\n".join(definition))
 break
else:
 print("try again beotch")


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.


--
https://mail.python.org/

Re: Installation of Slixfeed with pip fails

2024-08-03 Thread Thomas Passin via Python-list

On 8/3/2024 2:49 PM, Barry Scott via Python-list wrote:




On 30 Jul 2024, at 18:36, Schimon Jehudah via Python-list 
 wrote:

Greetings, to one and all!

My name is Schimon, and I am the developer of a news chat bot for the
XMPP network, called Slixfeed.

I have recently added support for OMEMO encryption, and a friend of
mine has reported that there is an issue installing it with pip.

I suppoes this is a fault of a package at PyPi, or a fault at my
pyproject.toml.

This is the link to the project:
https://git.xmpp-it.net/sch/Slixfeed#getting-started

Please advise,


This question is like asking "My car won't run. I suppose it's the 
engine. Please advise."



Please duplicate the problem and if after doing that you have not fixed
the problem post details here.

Barry




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





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


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

2024-07-30 Thread Thomas Passin via Python-list

On 7/30/2024 4:49 PM, marc nicole wrote:
OK, but how's the probability of small_ball greater than others? I can't 
find it anyway, what's its value?


It's your code. I wouldn't know. I suppose it's represented somewhere in 
all those parameters. You need to understand what those function calls 
are returning.  It's documented somewhere, right?


And you really do need to know the probabilities of the competing images 
because otherwise you won't know how confident you can be that the 
identification is a strong one.


Le mar. 30 juil. 2024 à 21:37, Thomas Passin via Python-list 
mailto:python-list@python.org>> a écrit :


On 7/30/2024 2:18 PM, 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:
 >
 >
 >
 >
 >
 >
 >
 >
 > class MultiObjectDetection():
 >
 >      def __init__(self, classes_name):
 >
 >          self._classes_name = classes_name
 >          self._num_classes = len(classes_name)
 >
 >          self._common_params = {'image_size': 448, 'num_classes':
 > self._num_classes,
 >                  'batch_size':1}
 >          self._net_params = {'cell_size': 7, 'boxes_per_cell':2,
 > 'weight_decay': 0.0005}
 >          self._net = YoloTinyNet(self._common_params,
self._net_params,
 > test=True)
 >
 >      def predict_object(self, image):
 >          predicts = self._net.inference(image)
 >          return predicts
 >
 >      def process_predicts(self, resized_img, predicts, thresh=0.2):
 >          """
 >          process the predicts of object detection with one image
input.
 >
 >          Args:
 >              resized_img: resized source image.
 >              predicts: output of the model.
 >              thresh: thresh of bounding box confidence.
 >          Return:
 >              predicts_dict: {"stick": [[x1, y1, x2, y2, scores1],
[...]]}.
 >          """
 >          cls_num = self._num_classes
 >          bbx_per_cell = self._net_params["boxes_per_cell"]
 >          cell_size = self._net_params["cell_size"]
 >          img_size = self._common_params["image_size"]
 >          p_classes = predicts[0, :, :, 0:cls_num]
 >          C = predicts[0, :, :, cls_num:cls_num+bbx_per_cell] # two
 > bounding boxes in one cell.
 >          coordinate = predicts[0, :, :, cls_num+bbx_per_cell:] # all
 > bounding boxes position.
 >
 >          p_classes = np.reshape(p_classes, (cell_size, cell_size,
1, cls_num))
 >          C = np.reshape(C, (cell_size, cell_size, bbx_per_cell, 1))
 >
 >          P = C * p_classes # confidencefor all classes of all
bounding
 > boxes (cell_size, cell_size, bounding_box_num, class_num) = (7, 7, 2,
 > 1).
 >
 >          predicts_dict = {}
 >          for i in range(cell_size):
 >              for j in range(cell_size):
 >                  temp_data = np.zeros_like(P, np.float32)
 >                  temp_data[i, j, :, :] = P[i, j, :, :]
 >                  position = np.argmax(temp_data) # refer to the class
 > num (with maximum confidence) for every bounding box.
 >                  index = np.unravel_index(position, P.shape)
 >
 >                  if P[index] > thresh:
 >                      class_num = index[-1]
 >                      coordinate = np.reshape(coordinate, (cell_size,
 > cell_size, bbx_per_cell, 4)) # (cell_size, cell_size,
 > bbox_num_per_cell, coordinate)[xmin, ymin, xmax, ymax]
 >                      max_coordinate = coordinate[index[0],
index[1], index[2], :]
 >
 >                      xcenter = max_coordinate[0]
 >                      ycenter = max_coordinate[1]
 >                      w = max_coordinate[2]
 >                      h = max_coordinate[3]
 >
 >                      xcenter = (index[1] + xcenter) *
(1.0*img_size /cell_size)
 >                      ycenter = (index[0] + ycenter) *
(1.0*img_size /cell_size)
 >
 >      

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

2024-07-30 Thread Thomas Passin via Python-list

On 7/30/2024 2:18 PM, 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:








class MultiObjectDetection():

 def __init__(self, classes_name):

 self._classes_name = classes_name
 self._num_classes = len(classes_name)

 self._common_params = {'image_size': 448, 'num_classes':
self._num_classes,
 'batch_size':1}
 self._net_params = {'cell_size': 7, 'boxes_per_cell':2,
'weight_decay': 0.0005}
 self._net = YoloTinyNet(self._common_params, self._net_params,
test=True)

 def predict_object(self, image):
 predicts = self._net.inference(image)
 return predicts

 def process_predicts(self, resized_img, predicts, thresh=0.2):
 """
 process the predicts of object detection with one image input.

 Args:
 resized_img: resized source image.
 predicts: output of the model.
 thresh: thresh of bounding box confidence.
 Return:
 predicts_dict: {"stick": [[x1, y1, x2, y2, scores1], [...]]}.
 """
 cls_num = self._num_classes
 bbx_per_cell = self._net_params["boxes_per_cell"]
 cell_size = self._net_params["cell_size"]
 img_size = self._common_params["image_size"]
 p_classes = predicts[0, :, :, 0:cls_num]
 C = predicts[0, :, :, cls_num:cls_num+bbx_per_cell] # two
bounding boxes in one cell.
 coordinate = predicts[0, :, :, cls_num+bbx_per_cell:] # all
bounding boxes position.

 p_classes = np.reshape(p_classes, (cell_size, cell_size, 1, cls_num))
 C = np.reshape(C, (cell_size, cell_size, bbx_per_cell, 1))

 P = C * p_classes # confidencefor all classes of all bounding
boxes (cell_size, cell_size, bounding_box_num, class_num) = (7, 7, 2,
1).

 predicts_dict = {}
 for i in range(cell_size):
 for j in range(cell_size):
 temp_data = np.zeros_like(P, np.float32)
 temp_data[i, j, :, :] = P[i, j, :, :]
 position = np.argmax(temp_data) # refer to the class
num (with maximum confidence) for every bounding box.
 index = np.unravel_index(position, P.shape)

 if P[index] > thresh:
 class_num = index[-1]
 coordinate = np.reshape(coordinate, (cell_size,
cell_size, bbx_per_cell, 4)) # (cell_size, cell_size,
bbox_num_per_cell, coordinate)[xmin, ymin, xmax, ymax]
 max_coordinate = coordinate[index[0], index[1], index[2], 
:]

 xcenter = max_coordinate[0]
 ycenter = max_coordinate[1]
 w = max_coordinate[2]
 h = max_coordinate[3]

 xcenter = (index[1] + xcenter) * (1.0*img_size /cell_size)
 ycenter = (index[0] + ycenter) * (1.0*img_size /cell_size)

 w = w * img_size
 h = h * img_size
 xmin = 0 if (xcenter - w/2.0 < 0) else (xcenter - w/2.0)
 ymin = 0 if (xcenter - w/2.0 < 0) else (ycenter - h/2.0)
 xmax = resized_img.shape[0] if (xmin + w) >
resized_img.shape[0] else (xmin + w)
 ymax = resized_img.shape[1] if (ymin + h) >
resized_img.shape[1] else (ymin + h)

 class_name = self._classes_name[class_num]
 predicts_dict.setdefault(class_name, [])
 predicts_dict[class_name].append([int(xmin),
int(ymin), int(xmax), int(ymax), P[index]])

 return predicts_dict

 def non_max_suppress(self, predicts_dict, threshold=0.5):
 """
 implement non-maximum supression on predict bounding boxes.
 Args:
 predicts_dict: {"stick": [[x1, y1, x2, y2, scores1], [...]]}.
 threshhold: iou threshold
 Return:
 predicts_dict processed by non-maximum suppression
 """
 for object_name, bbox in predicts_dict.items():
 bbox_array = np.array(bbox, dtype=np.float)
 x1, y1, x2, y2, scores = bbox_array[:,0], bbox_array[:,1],
bbox_array[:,2], bbox_array[:,3], bbox_array[:,4]
 areas = (x2-x1+1) * (y2-y1+1)
 order = scores.argsort()[::-1]
 keep = []
 while order.size > 0:
 i = order[0]
 keep.append(i)
 xx1 = np.maximum(x1[i], x1[order[1:]])
 yy1 = np.maximum(y1[i], y1[order[1:]])
 xx2 = np.minimum(x2[i], x2[order[1:]])
 yy2 = np.minimum(y2[i], y2[order[1

Re: Issue with pip Installation on My Laptop

2024-07-26 Thread Thomas Passin via Python-list

On 7/26/2024 7:25 AM, Lizna Shah via Python-list wrote:

OSError: [WinError 225] Operation did not complete successfully because the
file contains a virus or potentially unwanted software


That part of the error message tells you the story.  Windows thinks some 
file in the install has been corrupted with malware.


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


Re: Best use of "open" context manager

2024-07-06 Thread Thomas Passin via Python-list

On 7/6/2024 6:49 AM, 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,
not to mention that having "try" and "except" far apart decreases 
readability.


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.


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?


I usually read the file into a sequence of lines and then leave the 
open() as soon as possible.  Something like this:


FILENAME = 'this_is_an_example.txt'
lines = None
if os.path.exists(FILENAME):
with open(FILENAME) as f:
lines = f.readlines()
# do something with lines

Of course, if you want to read a huge number of lines you will need to 
be more thoughtful about it.  Or make all the processing within the 
open() block be a function.  Then you just have one more line in the block.


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


Re: Difference method vs attribut = function

2024-06-29 Thread Thomas Passin via Python-list

On 6/28/2024 12:08 PM, Ulrich Goebel via Python-list wrote:

Hi,

a class can have methods, and it can have attributes, which can hold a 
function. Both is well known, of course.

My question: Is there any difference?

The code snipped shows that both do what they should do. But __dict__ includes 
just the method, while dir detects the method and the attribute holding a 
function. My be that is the only difference?


class MyClass:
 def __init__(self):
 functionAttribute = None
 
 def method(self):

 print("I'm a method")

def function():
 print("I'm a function passed to an attribute")

mc = MyClass()
mc.functionAttribute = function

mc.method()
mc.functionAttribute()

print('Dict: ', mc.__dict__)# shows functionAttribute but not method
print('Dir:  ', dir(mc))# shows both functionAttribute and method


By the way: in my usecase I want to pass different functions to different 
instances of MyClass. It is in the context of a database app where I build 
Getters for database data and pass one Getter per instance.

Thanks for hints
Ulrich



https://docs.python.org/3/library/functions.html#dir -

object.__dict__¶
A dictionary or other mapping object used to store an object’s 
(writable) attributes.


dir(object)
...
With an argument, attempt to return a list of valid attributes for that 
object.


"functionAttribute" is a class method, not an instance method.  If you 
want an instance method:


class MyClass:
def __init__(self):
functionAttribute = None
self.instance_functionAttribute = None

def method(self):
print("I'm a method")

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


Re: Anonymous email users

2024-06-24 Thread Thomas Passin via Python-list

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.

Barry



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


Re: win32clipboard writing to clipboard on Windows 11

2024-06-17 Thread Thomas Passin via Python-list

On 6/17/2024 9:30 PM, MRAB via Python-list wrote:

On 2024-06-17 20:27, Rob Cliffe via Python-list wrote:

Recently I acquired a new laptop running WIndows 11; my previous one
uses WIndows 10.  I encountered a strange problem:
I am using the win32clipboard backage (part of pywin32), and when I use
SetClipboardData() to write text which consists ***entirely of digits***
to the clipboard, I either get an error (not always the same error
message) or a program crash.  The problem does not appear if I use
SetClipboardText() instead.  The problem does not occur on my old
machine (where I used the feature extensively).

Sample program:

from win32clipboard import *
OpenClipboard()
SetClipboardData(CF_UNICODETEXT, "A")
SetClipboardData(CF_UNICODETEXT, "A0")
SetClipboardData(CF_UNICODETEXT, "0A")
SetClipboardText("0", CF_UNICODETEXT)
print("OK so far")
SetClipboardData(CF_UNICODETEXT, "0")
CloseClipboard()

Sample output:

OK so far
Traceback (most recent call last):
    File "C:\TEST*.PY", line 8, in 
      SetClipboardData(CF_UNICODETEXT, "0")
pywintypes.error: (0, 'SetClipboardData', 'No error message is 
available')


Can anyone shed light on this?
Best wishes
Rob Cliffe


I tried it on Windows 10 and got this:

 >>> from win32clipboard import *
 >>> OpenClipboard()
 >>> SetClipboardData(CF_UNICODETEXT, "A")
1830508101640
 >>> CloseClipboard()
 >>> OpenClipboard()
 >>> SetClipboardData(CF_UNICODETEXT, "0")
Traceback (most recent call last):
   File "", line 1, in 
pywintypes.error: (6, 'SetClipboardData', 'The handle is invalid.')
 >>> CloseClipboard()

It looks like it's something to memory ownership:

https://stackoverflow.com/questions/1264137/how-to-copy-string-to-clipboard-in-c

If you're putting text on the clipboard, why not just use 
SetClipboardText()? That's what I do.


If you can make a change, and you only need to work with text on the 
clipboard, you could change to use pyperclip.  It also works on Linux, 
if you might care about that in the future.  It's available as a pip 
install. It's easier to use than the win32 approach.

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


Re: Couldn't install numpy on Python 2.7

2024-06-12 Thread Thomas Passin via Python-list

On 6/12/2024 1:59 PM, Chris Angelico via Python-list wrote:

On Thu, 13 Jun 2024 at 03:41, AVI GROSS via Python-list
 wrote:


Change is hard even when it may be necessary.

The argument often is about whether some things are necessary or not.

Python made a decision but clearly not a unanimous one.


What decision? To not release any new versions of Python 2? That isn't
actually the OP's problem here - the Python interpreter runs just
fine. But there's no numpy build for the OP's hardware and Python 2.7.

So if you want to complain about Python 2.7 being dead, all you have
to do is go through all of the popular packages and build binaries for
all modern computers. If that sounds easy, go ahead and do it; if it
sounds hard, realise that open source is not a democracy, and you
can't demand that other people do more and more and more unpaid work
just because you can't be bothered upgrading your code.


I support a Tomcat project that has some java code and most of the code 
is for Jython 2.7.  Jython 2.7 is approximately on a par with Python 
2.7.  Any Python-only code from the standard library will probably run, 
but of course any C extensions cannot.  The nice thing about using 
Jython in a java environment is that it can call any java object, and 
java code can call Jython objects and their methods.


The project cannot move to a Python-3 compatible version because Jython 
3.xx doesn't exist and may never exist.  The saving grace is that my 
project doesn't have to use packages like numpy, scipy, and so forth. 
Also, the project is very mature and almost certainly won't need to 
create functionality such packages would enable.  It would be nice to be 
able to use some newer parts of the standard library, but there it is. 
Jython does support "from __future__ import" and I make use of that for 
the print function and the like.



My current PC was not upgradable because of the new hardware requirement
Microsoft decided was needed for Windows 11.


Yes, and that's a good reason to switch to Linux for the older computer.


I have a 2012-vintage laptop that in modern terms has a very small 
supply of RAM and a very slow hard drive. When my newer Windows 10 
computer was going to be out of service for a while, I put a Linux 
distro on an external SSD and copied things I needed to work on to it, 
including my Thunderbird email profile directory.


Thunderbird and everything else worked perfectly for me during that 
week.  True, there were a few Windows-only programs I missed, but I used 
other similar programs even if I didn't like them as much.  It's amazing 
how little resources Linux installs need, even with a GUI.  Of course, 
4GB RAM is limiting whether you are on Linux or Windows - you can't 
avoid shuffling all those GUI bits around - but with a little care it 
worked great.  And with the external SSD the laptop was a lot snappier 
than it ever was when it was new.



I mention this in the context of examples of why even people who are fairly
knowledgeable do not feel much need to fix what does not feel broken.


It doesn't feel broken, right up until it does. The OP has discovered
that it *IS* broken. Whining that it doesn't "feel broken" is nonsense
when it is, in fact, not working.


When is Python 4 coming?


Is this just another content-free whine, or are you actually curious
about the planned future of Python? If the latter, there is **PLENTY**
of information out there and I don't need to repeat it here.

Please don't FUD.

ChrisA


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


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

2024-06-08 Thread Thomas Passin via Python-list
rt of Venn Diagram  chart 
to change the font size. Why? Because some of the labels were long and the 
relative sizes of the pie slices were not known till an analysis of the data 
produced the appropriate numbers and ratios. This was a case where the 
documentation of the function used by them did not suggest how to do many 
things as it called a function that called others to quite some depth. A few 
simple experiments and some guesses and exploration showed me ways to pass 
arguments along that were not documented but that were passed properly down the 
chain and I could now change the text size and quite a few other things. But I 
asked myself if this was really the right solution the client needed. I then 
made a guess on how I could get the long text wrapped into multiple lines that 
fit into the sections of the Venn Diagram without shrinking the text at all, or 
as much. The client had not considered that as an option, but it was better for 
their display than required. But until people see such output, unless they have 
lots of experience, it cannot be expected they can tell you up-front what they 
want.

One danger of languages like Python is that often people get the code you 
supply and modify it themselves or reuse it on some project they consider 
similar. That can be a good thing but often a mess as you wrote the code to do 
things in a specific way for a specific purpose ...


-Original Message-----
From: Python-list  On 
Behalf Of Thomas Passin via Python-list
Sent: Saturday, June 8, 2024 1:10 PM
To: python-list@python.org
Subject: Re: From JoyceUlysses.txt -- words occurring exactly once

On 6/8/2024 11:54 AM, Larry Martell via Python-list wrote:

On Sat, Jun 8, 2024 at 10:39 AM Mats Wichmann via Python-list <
python-list@python.org> wrote:


On 6/5/24 05:10, Thomas Passin via Python-list wrote:


Of course, we see this lack of clarity all the time in questions to the
list.  I often wonder how these askers can possibly come up with
acceptable code if they don't realize they don't truly know what it's
supposed to do.


Fortunately, having to explain to someone else why something is giving
you trouble can help shed light on the fact the problem statement isn't
clear, or isn't clearly understood. Sometimes (sadly, many times it
doesn't).



The original question struck me as homework or an interview question for a
junior position. But having no clear requirements or specifications is good
training for the real world where that is often the case. When you question
that, you are told to just do something, and then you’re told it’s not what
is wanted. That frustrates people but it’s often part of the process.
People need to see something to help them know what they really want.


At the extremes, there are two kinds of approaches you are alluding to.
One is what I learned to call "rock management": "Bring me a rock ...
no, that's not the right one, bring me another ... no that's not what
I'm looking for, bring me another...".  If this is your situation, so,
so sorry!

At the other end, there is a mutual evolution of the requirements
because you and your client could not have known what they should be
until you have spent effort and time feeling your way along.  With the
right client and management, this kind of project can be a joy to work
on.  I've been lucky enough to have worked on several projects of this kind.

In truth, there always are requirements.  Often (usually?) they are not
thought out, not consistent, not articulated clearly, and not
communicated well. They may live only in the mind of one person.



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


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

2024-06-08 Thread Thomas Passin via Python-list

On 6/8/2024 11:54 AM, Larry Martell via Python-list wrote:

On Sat, Jun 8, 2024 at 10:39 AM Mats Wichmann via Python-list <
python-list@python.org> wrote:


On 6/5/24 05:10, Thomas Passin via Python-list wrote:


Of course, we see this lack of clarity all the time in questions to the
list.  I often wonder how these askers can possibly come up with
acceptable code if they don't realize they don't truly know what it's
supposed to do.


Fortunately, having to explain to someone else why something is giving
you trouble can help shed light on the fact the problem statement isn't
clear, or isn't clearly understood. Sometimes (sadly, many times it
doesn't).



The original question struck me as homework or an interview question for a
junior position. But having no clear requirements or specifications is good
training for the real world where that is often the case. When you question
that, you are told to just do something, and then you’re told it’s not what
is wanted. That frustrates people but it’s often part of the process.
People need to see something to help them know what they really want.


At the extremes, there are two kinds of approaches you are alluding to. 
One is what I learned to call "rock management": "Bring me a rock ... 
no, that's not the right one, bring me another ... no that's not what 
I'm looking for, bring me another...".  If this is your situation, so, 
so sorry!


At the other end, there is a mutual evolution of the requirements 
because you and your client could not have known what they should be 
until you have spent effort and time feeling your way along.  With the 
right client and management, this kind of project can be a joy to work 
on.  I've been lucky enough to have worked on several projects of this kind.


In truth, there always are requirements.  Often (usually?) they are not 
thought out, not consistent, not articulated clearly, and not 
communicated well. They may live only in the mind of one person.


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


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

2024-06-06 Thread Thomas Passin via Python-list

On 6/5/2024 12:33 AM, dn via Python-list wrote:

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 one's been kicking around for years ... good job in finding a link 
for it!


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.


Of course, we see this lack of clarity all the time in questions to the 
list.  I often wonder how these askers can possibly come up with 
acceptable code if they don't realize they don't truly know what it's 
supposed to do.



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




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


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

2024-06-01 Thread Thomas Passin via Python-list

On 6/1/2024 4:04 AM, Peter J. Holzer via Python-list wrote:

On 2024-05-30 19:26:37 -0700, HenHanna via Python-list wrote:

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


Especially since the same character is used as both an apostrophe and a
closing quotation mark. And while that's pretty unambiguous between to
characters it isn't at the end of a word:

 This is Alex’ house.
 This type of building is called an ‘Alex’ house.
 The sentence ‘We are meeting at Alex’ house’ contains an apostrophe.

(using proper unicode quotation marks. It get's worse if you stick to
ASCII.)

Personally I like to use U+0027 APOSTROPHE as an apostrophe and U+2018
LEFT SINGLE QUOTATION MARK and U+2019 RIGHT SINGLE QUOTATION MARK as
single quotation marks[1], but despite the suggestive names, this is not
the common typographical convention, so your texts are unlikely to make
this distinction.

 hp

[1] Which I use rarely, anyway.


My usual approach is to replace punctuation by spaces and then to 
discard anything remaining that is only one character long (or sometimes 
two, depending on what I'm working on).  Yes, OK, I will miss words like 
"I". Usually I don't care about them. Make exceptions to the policy if 
you like.


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


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

2024-05-31 Thread Thomas Passin via Python-list

On 5/30/2024 4:03 PM, 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.


You will probably get a thousand different suggestions, but here's a 
fairly direct and readable one in Python:


s1 = 'Is this word is the only word repeated in this string'

counts = {}
for w in s1.lower().split():
counts[w] = counts.get(w, 0) + 1
print(sorted(counts.items()))
# [('in', 1), ('is', 2), ('only', 1), ('repeated', 1), ('string', 1), 
('the', 1), ('this', 2), ('word', 2)]


Of course you can adjust the definition of what constitutes a word, 
handle punctuation and so on, and tinker with the output format to suit 
yourself.  You would replace s1.lower().split() with, e.g., 
my_custom_word_splitter(s1).



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


Re: Flubbed it in the second interation through the string: range error... HOW?

2024-05-29 Thread Thomas Passin via Python-list

On 5/29/2024 10:59 AM, MRAB via Python-list wrote:

On 2024-05-29 15:32, Thomas Passin via Python-list wrote:

On 5/29/2024 8:55 AM, Kevin M. Wilson wrote:
Please recall, I said the format for the email failed to retain the 
proper indents.

I'll attach a picture of the code!
Purpose; to uppercase every other letter in a string.

Thanks all, KMW


Simpler is good, and readability is good.  For a simple conversion that
has a little touch of generality:

s1 = 'this is a test'
def convert(i, ch):
  return ch.upper() if i % 2 else ch

result = ''.join([convert(i, ch) for i, ch in enumerate(s1)])
print(result)  # tHiS Is a tEsT


[snip]
Small mistake there. The original code converted to uppercase on even 
indexes, whereas your code does it on odd ones.


I wondered if anyone would catch that :)  Anyway, I don't think the 
original question was whether to start with even or odd but ways to 
iterate character by character and do something, right?



However, this has a weakness: what to do about spaces.  Should they be
counted among the characters to be uppercased? or should they not be
included in the count of the alternation?  If you want to uppercase
every other letter that is not a space, things become a little more
complicated.  And then do you want this to apply to all whitespace or
only spaces?

If you want to skip changing spaces, then you need to track the state of
converted characters in some way.  It would probably be easier (and more
readable) to use a "for x in t:" construction:


Actually, I did mess up the action for a space.  It should be:

def convert(convert_this, ch):
"""Convert character ch if convert_this is True.
Don't convert spaces.
"""
if ch == ' ':
   return (convert_this, ch)
if convert_this:
   return (False, ch.upper())
return (True, ch)

We should never get two printable uppercased characters in a row, even 
if there is a space between them, but my original convert(convert_this, 
ch) did.



def convert(convert_this, ch):
  """Convert character ch if convert_this is True.
  Don't convert spaces.
  """
  if convert_this:
  if ch == ' ':
  return (convert_this, ch)
  elif convert_this:
  return (False, ch.upper())
  return (True, ch)

convert_next = False
result = ''
for ch in s1:
  convert_next, ch = convert(convert_next, ch)
  result += ch
print(result)  # tHiS Is A TeSt

There could be even more complications if you allow non-ascii characters
but you were asking about processing character by character so I won't
get into that.

(You haven't specified the problem in enough detail to answer questions
like those).


[snip]




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


Re: Flubbed it in the second interation through the string: range error... HOW?

2024-05-29 Thread Thomas Passin via Python-list

On 5/29/2024 8:55 AM, Kevin M. Wilson wrote:
Please recall, I said the format for the email failed to retain the 
proper indents.

I'll attach a picture of the code!
Purpose; to uppercase every other letter in a string.

Thanks all, KMW


Simpler is good, and readability is good.  For a simple conversion that 
has a little touch of generality:


s1 = 'this is a test'
def convert(i, ch):
return ch.upper() if i % 2 else ch

result = ''.join([convert(i, ch) for i, ch in enumerate(s1)])
print(result)  # tHiS Is a tEsT

However, this has a weakness: what to do about spaces.  Should they be 
counted among the characters to be uppercased? or should they not be 
included in the count of the alternation?  If you want to uppercase 
every other letter that is not a space, things become a little more 
complicated.  And then do you want this to apply to all whitespace or 
only spaces?


If you want to skip changing spaces, then you need to track the state of 
converted characters in some way.  It would probably be easier (and more 
readable) to use a "for x in t:" construction:


def convert(convert_this, ch):
"""Convert character ch if convert_this is True.
Don't convert spaces.
"""
if convert_this:
if ch == ' ':
return (convert_this, ch)
elif convert_this:
return (False, ch.upper())
return (True, ch)

convert_next = False
result = ''
for ch in s1:
convert_next, ch = convert(convert_next, ch)
result += ch
print(result)  # tHiS Is A TeSt

There could be even more complications if you allow non-ascii characters 
but you were asking about processing character by character so I won't 
get into that.


(You haven't specified the problem in enough detail to answer questions 
like those).





***
"When you pass through the waters, I will be with you: and when you pass 
through the rivers, they will not sweep over you. When you walk through 
the fire, you will not be burned: the flames will not set you ablaze."

*Isaiah 43:2
*


On Wednesday, May 29, 2024 at 06:19:56 AM MDT, Thomas Passin via 
Python-list  wrote:



On 5/29/2024 3:14 AM, Chris Angelico via Python-list wrote:
 > On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list
 > mailto:python-list@python.org>> wrote:
 >> By which Thomas means stuff like this:
 >>
 >>      print(f'if block {name[index]} and index {index}')
 >>
 >> Notice the leading "f'". Personally I wouldn't even go that far, just:
 >>
 >>      print('if block', name[index], 'and index', index)
 >>
 >> But there are plenty of places where f-strings are very useful.
 >
 > I wouldn't replace str.format() everywhere, nor would I replace
 > percent encoding everywhere - but in this case, I think Thomas is
 > correct. Not because it's 2024 (f-strings were brought in back in
 > 2015, so they're hardly chronologically special),

I only meant that they have been around for 9 years and are usually more
readable, so just change over already.  I had some inertia over them
myself (imagine sticking with % formatting!) so I understand.


 > but because most of
 > this looks like debugging output that can take advantage of this
 > feature:
 >
 > print(f"if block {name[index]=} {index=}")
 >
 > ChrisA

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


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


Re: Flubbed it in the second interation through the string: range error... HOW?

2024-05-29 Thread Thomas Passin via Python-list

On 5/29/2024 3:14 AM, Chris Angelico via Python-list wrote:

On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list
 wrote:

By which Thomas means stuff like this:

  print(f'if block {name[index]} and index {index}')

Notice the leading "f'". Personally I wouldn't even go that far, just:

  print('if block', name[index], 'and index', index)

But there are plenty of places where f-strings are very useful.


I wouldn't replace str.format() everywhere, nor would I replace
percent encoding everywhere - but in this case, I think Thomas is
correct. Not because it's 2024 (f-strings were brought in back in
2015, so they're hardly chronologically special),


I only meant that they have been around for 9 years and are usually more 
readable, so just change over already.  I had some inertia over them 
myself (imagine sticking with % formatting!) so I understand.



but because most of
this looks like debugging output that can take advantage of this
feature:

print(f"if block {name[index]=} {index=}")

ChrisA


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


Re: Flubbed it in the second interation through the string: range error... HOW?

2024-05-28 Thread Thomas Passin via Python-list
Your code is unreadable. The lines have all run together.  And after 
that, kindly explain what you want your code sample to do.  "Process" 
doesn't say much.


From what I can make out about what you are trying to do, you would do 
better to index through your string with


for i, chr in enumerate(name):
# do something with the character

Also, it's 2024 ... time to start using f-strings (because they are more 
readable than str.format())


On 5/29/2024 12:33 AM, Kevin M. Wilson via Python-list wrote:

The following is my effort to understand how to process a string, letter, by 
letter:
def myfunc(name):        index = 0    howmax = len(name)    # while (index <= 
howmax):    while (index < howmax):        if (index % 2 == 0):            
print('letter to upper = {}, index {}!'.format(name[index], index))            name = 
name[index].upper()            print('if block {} and index {}'.format(name[index], 
index))        elif (index % 2 > 0):            print(index)            print('Start: 
elseif block, index is {}, letter is {}'.format(index, name))            # print('letter 
to lower = {}'.format(name[index]))            # print('Already lowercase do noting: 
name = {}'.format(name[index]))        index += 1        # index = name.upper()
     return name
myfunc('capitalism')
Error message:                        Not making sense, index is 1, letter s/b 
'a'letter to upper = c, index 0!
if block C and index 0
1
Start: elseif block, index is 1, letter is C
---
IndexErrorTraceback (most recent call last)
Cell In[27], line 21
  17 # index = name.upper()
  19 return name
---> 21 myfunc('capitalism')

Cell In[27], line 8, in myfunc(name)
   6 while (index < howmax):
   7 if (index % 2 == 0):
> 8 print('letter to upper = {}, index {}!'.format(name[index], 
index))
   9 name = name[index].upper()
  10 print('if block {} and index {}'.format(name[index], index))

IndexError: string index out of 
range***
So, I'm doing something... Stupid!!
***
"When you pass through the waters, I will be with you: and when you pass through the 
rivers, they will not sweep over you. When you walk through the fire, you will not be 
burned: the flames will not set you ablaze."
Isaiah 43:2


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


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

2024-05-27 Thread Thomas Passin via Python-list

On 5/26/2024 2:28 AM, 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:

```python

import os

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


There are different flavors of Markdown, so that might be a factor so 
far as details of the block are concerned.


What do you mean by it not "working"?  What do you see and what did you 
expect to see?  What did you see different when you used the next example?


How did you generate the output HTML file?


However, that is not the case. At least not for me (using Python 3.12.3).
If instead I type it:

 #!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.

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

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.

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



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


Re: Terminal Emulator (Posting On Python-List Prohibited)

2024-05-19 Thread Thomas Passin via Python-list

On 5/19/2024 6:00 PM, Karsten Hilbert via Python-list wrote:

Am Sun, May 19, 2024 at 10:45:09PM +0100 schrieb Barry via Python-list:


On 18 May 2024, at 16:27, Peter J. Holzer via Python-list 
 wrote:

I don't think Linux users have to deal with venvs


Modern debian (ubuntu) and fedora block users installing using pip.
You must use a venv to pip install packages from pypi now.


Which makes one wonder how one is supposed to package Python
applications requiring modules not yet packaged by Debian.


I confess, I sometimes install those packages using pip's self-warning 
option "--break-system-packages".  Naturally I only install them with 
--user.  Another option besides venvs is to install a different version 
of Python from python.org, not by using the system installer.  For 
example, if your system version is, say, 3.8.10 (as it is on my Mint 
VM), install 3.11.9 and make sure you always launch pip with


python3.11 -m pip 

I have done this on some VMs, and use the system's Python on some 
others.  Happily none of my Linux VMs are critical for anything.  I can 
blow them away and recreate them without worry.


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


Re: Terminal Emulator (Posting On Python-List Prohibited)

2024-05-19 Thread Thomas Passin via Python-list

On 5/19/2024 6:34 PM, Grant Edwards via Python-list wrote:

On 2024-05-19, Barry via Python-list  wrote:




On 18 May 2024, at 16:27, Peter J. Holzer via Python-list 
 wrote:

I don't think Linux users have to deal with venvs


Modern debian (ubuntu) and fedora block users installing using pip.


You can't even use pip to do "user" installs?


Nope, often not.  The error messages I've gotten do tell you to use the 
"--break-system-packages" flag if you really, really want to install the 
package.  So


python3 -m pip install --user --break-system-packages [--upgrade] 



Or install an additional version of Python that isn't managed by the system.


Grant



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


Re: Terminal Emulator (Posting On Python-List Prohibited)

2024-05-19 Thread Thomas Passin via Python-list

On 5/19/2024 6:08 PM, Skip Montanaro via Python-list wrote:

Modern debian (ubuntu) and fedora block users installing using pip.




Even if you're telling it to install in ~/.local? I could see not allowing
to run it as root.

I honestly haven't tried. Maybe I should... 🤔 I have an old laptop running
XUbuntu 22.04 which I generally only use to compile the most recent
branches on GitHub (main, 3.12, & 3.13 at the moment).


On some (maybe all) of my Linux VMs, pip - the one installed for the 
system - won't install something even with --user unless you use the 
--break-system-packages flag.


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


Re: Terminal Emulator (Posting On Python-List Prohibited)

2024-05-19 Thread Thomas Passin via Python-list

On 5/19/2024 3:32 AM, Alan Gauld via Python-list wrote:

On 18/05/2024 19:12, Piergiorgio Sartor via Python-list wrote:


[snip] 



The dependency nightmare created by python, pip
and all the rest cannot be resolved otherwise.


I've honestly never experienced this "nightmare".
I install stuff and it just works.


One way it can bite even you is if you have a program installed whose 
requirements claim it needs a certain library of version no higher than 
X, and you already already have a later version of that library 
installed since one of your other programs requires it.  Pip won't 
install the new program because of this conflict.


In reality, you may know the the new program would work fine with the 
version of the library you installed, but the packagers of the new 
program didn't realize they should have updated their requirements.


With venvs, you can have separate environments for each.  Of course this 
doesn't help if you need both packages in the same environment...





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


Re: help

2024-05-13 Thread Thomas Passin via Python-list

On 5/12/2024 7:56 PM, Enrder via Python-list wrote:

good tader

I need help to install the bcml, and is that after installing the python
and I go to the command prompt and put ''pip install bcml'' to install it
tells me "pip" is not recognized as an internal or external command,
program or executable batch file.

I have tried everything, uninstalling and installing, restoring it,
activating and deactivating all the checkboxes that appear in the options
section, I searched the internet and the same thing keeps happening to me.



If you can help me, I would appreciate it very much.


Launch pip using the following command.  If you don't run python using 
the name "python" then use the name you usually use (e.g., "py", 
"python3", etc.) -


python -m pip install bcml

This command causes Python to load and run its own copy of pip.  So the 
fact that the operating system can't find it doesn't matter.  You should 
always run pip this way, especially if you end up with several different 
versions of Python on the same computer.


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


Re: how to discover what values produced an exception?

2024-05-03 Thread Thomas Passin via Python-list

On 5/3/2024 9:56 AM, Johanne Fairchild via Python-list wrote:

How to discover what values produced an exception?  Or perhaps---why
doesn't the Python traceback show the values involved in the TypeError?
For instance:

--8<>8---

(0,0) < 4

Traceback (most recent call last):
   File "", line 1, in 
TypeError: '<' not supported between instances of 'tuple' and 'int'
--8<>8---

It could have said something like:

--8<>8---
TypeError: '<' not supported between instances of 'tuple' and 'int'
   in (0,0) < 4.
--8<>8---

We would know which were the values that caused the problem, which would
be very helpful.


In this example it would not help at all to know the actual values. 
Knowing that you are trying to compare incomparable types is enough.


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


Re: First two bytes of 'stdout' are lost

2024-04-11 Thread Thomas Passin via Python-list

On 4/11/2024 8:42 AM, Olivier B. via Python-list wrote:

I am trying to use StringIO to capture stdout, in code that looks like this:

import sys
from io import StringIO
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
print( "patate")
mystdout.seek(0)
sys.stdout = old_stdout
print(mystdout.read())

Well, it is not exactly like this, since this works properly

This code is actually run from C++ using the C Python API.
This worked quite well, so the code was right at some point. But now,
two things changed:
  - Now using python 3.11.7 instead of 3.7.12
  - Now using only the python limited C API

And it seems that now, mystdout.read() always misses the first two
characters that have been written to stdout.

My first ideas was something related to the BOM improperly truncated
at some point, but i am manipulating UTF-8, so the bom would be 3
bytes, not 2.

I ruled out wrong C++ code to extract the string from the python
variable, since running a python print of the content of mystdout in
the real stdout also misses the two first characters.

Hopefully someone has a clue on what would have changed in Python for
this to stop working compared to python 3.7?


I've not used the C API, so just for fun I asked ChatGPT about this and 
it suggested that a flush after writing to StringIO might do it.  It 
suggested using a custom class for this purpose:


class MyStringIO(StringIO):
def write(self, s):
# Override write method to ensure all characters are written 
correctly

super().write(s)
self.flush()

You would use it like this:

sys.stdout = mystdout = MyStringIO()

I haven't tested it but it seems reasonable, although I would have 
naively expected to lose bytes from the end, not the beginning.

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


Re: How to Add ANSI Color to User Response

2024-04-10 Thread Thomas Passin via Python-list

On 4/10/2024 6:41 PM, Alan Gauld via Python-list wrote:

On 10/04/2024 19: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


Normally, for any kind of fancy terminal work, I'd say use curses.
But I suspect Jython may not support curses?

On the offchance it does do curses it would look like:

import curses

def main(scr):
if curses.has_colors():  # check the terminal supports color
   curses.start_color().  # init the color system
   curses.init_pair(1,curses.COLOR_YELLOW,curses.COLOR_BLUE)

   # Now start adding text coloring as desired...
   scr.addstr(0,0,"This string is yellow and blue",
  curses.color_pair(1))

   scr.refresh().  # make it visible
else: scr.addstr("Sorry, no colors available")

curses.wrapper(main)

HTH


Curses is a C module, and there is a Python interface to it.   Jython 
would have to find an equivalent Java library.  Still, isn't the case 
that the terminal color output commands are pretty standard?  They could 
just be stuck into the output string.  Doing more fancy things, like 
moving the cursor arbitrarily, probably differ but the OP just mentioned 
colors.


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


Re: ModuleNotFoundError: No module named 'Paramiko'

2024-04-08 Thread Thomas Passin via Python-list

On 4/8/2024 3:35 PM, Keith Thompson via Python-list wrote:

Thomas Passin  writes:

On 4/8/2024 2:01 PM, Dietmar Schwertberger via Python-list wrote:

To be sure, you can always go the the directory of the Python
interpreter and open a cmd window there.
(By entering 'cmd' into the explorer address bar.)
Then enter 'python.exe -mpip install paramiko'.
This way you can be sure that you're not running a pip.exe that
belongs to another Python interpreter.


This is not quite right. The best name of the Python executable may or
may not be "python.exe".  The command line needs a space after the
"-m":


No, the option and its argument can be bundled.  "-mpip" is equivalent
to "-m pip".  (The space might make it clearer for human readers.)


Oh, surprise, thanks for the correction. My apologies to Dietmar. I'd 
stick with the space, though, because it's often required by other 
programs.  No sense developing a conflicting habit...


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


Re: ModuleNotFoundError: No module named 'Paramiko'

2024-04-08 Thread Thomas Passin via Python-list

On 4/8/2024 2:01 PM, Dietmar Schwertberger via Python-list wrote:
To be sure, you can always go the the directory of the Python 
interpreter and open a cmd window there.

(By entering 'cmd' into the explorer address bar.)
Then enter 'python.exe -mpip install paramiko'.
This way you can be sure that you're not running a pip.exe that belongs 
to another Python interpreter.


This is not quite right. The best name of the Python executable may or 
may not be "python.exe".  The command line needs a space after the "-m":


 -m pip install 

For , you can check if "python" runs the intended 
version by using the -V option (must be capitalized):


python -V

On Windows, Python from python.org usually installs a launcher named 
"py", which will run the last version installed:


py -m pip install ...

Or it can run a specific version, e.g.:

py -3.7 -m pip install ...

This will run Python 3.7 if installed.

On Linux, you can run the desired version with, e.g.,

python3.7 -m pip ...
--
https://mail.python.org/mailman/listinfo/python-list


Re: Running issues

2024-04-05 Thread Thomas Passin via Python-list

On 4/5/2024 5:32 PM, shannon makasale via Python-list wrote:

Hi there,
My name is Shannon. I installed Python 3.12 on my laptop a couple months ago, 
but realised my school requires me to use 3.11.1.

I uninstalled 3.12 and installed 3.11.1.

Unfortunately, I am unable to run python now. It keeps asking to be modified, 
repaired or uninstalled.

Do you have any suggestions on how to fix this?


It would be helpful to know how you uninstalled it.

The message you saw looks like it comes from the installer rather than 
from the Python interpreter.  Try invoking Python with "py" (assuming 
you are using Windows). That is the standard Python launcher that is 
installed by the installer from python.org.


For the future, know that you can have several different versions of 
Python installed at the same time.  On Windows, you can launch a 
specific version using the launcher:


py -3.11
py -3.12

And so on.

On Linux you should use the full name, such as

python3.11
python3.12

etc., depending on which versions have been installed.  "python3" will 
get you the version used by the system, which may not be the one you 
want to use.


To install Python packages with pip, make sure you specify which version 
of pip to use, like this:


py -3.11 -m pip (Windows)

or

python3.11 -m pip (Linux)

Otherwise you make accidentally install the package into the wrong 
Python installation.



Any help you can offer is greatly appreciated. Thank you for your time.


Hope to hear from you soon.



Shannon Makasale


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


Re: A technique from a chatbot

2024-04-04 Thread Thomas Passin via Python-list

On 4/4/2024 3:03 PM, Mark Bourne via Python-list wrote:

Thomas Passin wrote:

On 4/2/2024 1:47 PM, Piergiorgio Sartor via Python-list wrote:

On 02/04/2024 19.18, Stefan Ram wrote:

   Some people can't believe it when I say that chatbots improve
   my programming productivity. So, here's a technique I learned
   from a chatbot!
   It is a structured "break". "Break" still is a kind of jump,
   you know?
   So, what's a function to return the first word beginning with
   an "e" in a given list, like for example
[ 'delta', 'epsilon', 'zeta', 'eta', 'theta' ]

   ? Well it's
def first_word_beginning_with_e( list_ ):
 for word in list_:
 if word[ 0 ]== 'e': return word

   . "return" still can be considered a kind of "goto" statement.
   It can lead to errors:

def first_word_beginning_with_e( list_ ):
 for word in list_:
 if word[ 0 ]== 'e': return word
 something_to_be_done_at_the_end_of_this_function()
   The call sometimes will not be executed here!
   So, "return" is similar to "break" in that regard.
   But in Python we can write:
def first_word_beginning_with_e( list_ ):
 return next( ( word for word in list_ if word[ 0 ]== 'e' ), None )


Doesn't look a smart advice.


   . No jumps anymore, yet the loop is aborted on the first hit


It's worse than "not a smart advice". This code constructs an 
unnecessary tuple, then picks out its first element and returns that.


I don't think there's a tuple being created.  If you mean:
     ( word for word in list_ if word[ 0 ]== 'e' )

...that's not creating a tuple.  It's a generator expression, which 
generates the next value each time it's called for.  If you only ever 
ask for the first item, it only generates that one.


Yes, I was careless when I wrote that. Still, the tuple machinery has to 
be created and that's not necessary here. My point was that you are 
asking the Python machinery to do extra work for no benefit in 
performance or readability.


When I first came across them, I did find it a bit odd that generator 
expressions look like the tuple equivalent of list/dictionary 
comprehensions.


FWIW, if you actually wanted a tuple from that expression, you'd need to 
pass the generator to tuple's constructor:

     tuple(word for word in list_ if word[0] == 'e')
(You don't need to include an extra set of brackets when passing a 
generator a the only argument to a function).




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


Re: Help Needed With a Python Gaming Module

2024-04-03 Thread Thomas Passin via Python-list

On 4/3/2024 3:06 PM, WordWeaver Evangelist via Python-list wrote:

Hello everyone! It has been a l-o-n-g time -- nine years in fact --since I last 
participated on this mailing list.


[snip]

3. You are very familiar with the Jython 2 environment, which I am told is 
based on Python 2 and NOT Python 3.


Yes, Jython 2 is currently more or less even with Python 2.7.

You are presumably writing or hosting this in a java environment, and 
you may not realize that you can call Jython code from a java class 
(calling java classes from Jython code is dead simple).  For example, I 
have some java servlet classes that invoke Jython classes and call their 
methods.  If that sounds useful for your project, I can let you know how 
to do it.


[more snips...]

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


Re: A technique from a chatbot

2024-04-03 Thread Thomas Passin via Python-list

On 4/3/2024 1:27 AM, AVI GROSS via Python-list wrote:

I am a tad confused by a suggestion that any kind of GOTO variant is bad. The 
suggestion runs counter to the reality that underneath it all, compiled 
programs are chock full of GOTO variants even for simple things like IF-ELSE.

Consider the code here:


def first_word_beginning_with_e( list_ ):
  for word in list_:
  if word[ 0 ]== 'e': return word
  something_to_be_done_at_the_end_of_this_function()


If instead the function initialized a variable to nothing useful and in the 
loop if it found a word beginning with e and it still contained nothing useful, 
copied it into the variable and then allowed the code to complete the loop and 
finally returned the variable, that would simply be a much less efficient 
solution to the problem and gain NOTHING. There are many variants you can come 
up with and when the conditions are complex and many points of immediate 
return, fine, then it may be dangerous. But a single return is fine.

The function does have a flaw as it is not clear what it should do if nothing 
is found. Calling a silly long name does not necessarily return anything.

Others, like Thomas, have shown other variants including some longer and more 
complex ways.

A fairly simple one-liner version, not necessarily efficient, would be to just 
use a list comprehension that makes a new list of just the ones matching the 
pattern of starting with an 'e' and then returns the first entry or None. This 
shows the code and test it:

text = ["eastern", "Western", "easter"]

NorEaster = ["North", "West", "orient"]

def first_word_beginning_with_e( list_ ):
   return(result[0] if (result := [word for word in list_ if word[0].lower() == 
'e']) else None)

print(first_word_beginning_with_e( text ))
print(first_word_beginning_with_e( NorEaster ))

Result of running it on a version of python ay least 3.8 so it supports the 
walrus operator:

eastern
None


The OP seems to want to return None if a match is not found.  If a 
Python function ends without a return statement, it automatically 
returns None.  So nothing special needs to be done.  True, that is 
probably a special case, but it suggests that the problem posed to the 
chatbot was not posed well.  A truly useful chatbot could have discussed 
many of the points we've been discussing.  That would have made for a 
good learning experience.  Instead the chatbot produced poorly 
constructed code that caused a bad learning experience.




[snip...]


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


Re: A technique from a chatbot

2024-04-02 Thread Thomas Passin via Python-list

On 4/2/2024 1:47 PM, Piergiorgio Sartor via Python-list wrote:

On 02/04/2024 19.18, Stefan Ram wrote:

   Some people can't believe it when I say that chatbots improve
   my programming productivity. So, here's a technique I learned
   from a chatbot!
   It is a structured "break". "Break" still is a kind of jump,
   you know?
   So, what's a function to return the first word beginning with
   an "e" in a given list, like for example
[ 'delta', 'epsilon', 'zeta', 'eta', 'theta' ]

   ? Well it's
def first_word_beginning_with_e( list_ ):
 for word in list_:
 if word[ 0 ]== 'e': return word

   . "return" still can be considered a kind of "goto" statement.
   It can lead to errors:

def first_word_beginning_with_e( list_ ):
 for word in list_:
 if word[ 0 ]== 'e': return word
 something_to_be_done_at_the_end_of_this_function()
   The call sometimes will not be executed here!
   So, "return" is similar to "break" in that regard.
   But in Python we can write:
def first_word_beginning_with_e( list_ ):
 return next( ( word for word in list_ if word[ 0 ]== 'e' ), None )


Doesn't look a smart advice.


   . No jumps anymore, yet the loop is aborted on the first hit


It's worse than "not a smart advice". This code constructs an 
unnecessary tuple, then picks out its first element and returns that. 
The something_to_be_done() function may or may not be called.  And it's 
harder to read and understand than necessary.  Compare, for example, 
with this version:


def first_word_beginning_with_e(target, wordlist):
result = ''
for w in wordlist:
if w.startswith(target):
res = w
break
do_something_else()
return result

If do_something_else() is supposed to fire only if the target is not 
found, then this slight modification will do:


def first_word_beginning_with_e(target, wordlist):
result = ''
for w in wordlist:
if w.startswith(target):
res = w
break
else:
do_something_else()
return result

[Using the "target" argument instead of "target[0]" will let you match 
an initial string instead of just a the first character].



First of all, I fail to understand why there
should be no jumps any more.
It depends on how "return" and "if" are handled,
I guess, in different context.
Maybe they're just "masked".
In any case, the "compiler" should have just
done the same.


   (if I guess correctly how its working).


Second, it is difficult to read, which is bad.
The "guess" above is just evidence of that.

My personal opinion about these "chatbots", is
that, while they might deliver clever solutions,
they are not explaining *why* these solutions
should be considered "clever".
Which is the most important thing (the solution
itself is _not_).

bye,



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


Re: the name ``wheel''

2024-03-21 Thread Thomas Passin via Python-list

On 3/21/2024 4:19 PM, Grant Edwards via Python-list wrote:

On 2024-03-21, MRAB via Python-list  wrote:


As it's recommended to use the Python Launcher py on Windows, I use
that instead:

py -m pip install something

because it gives better support if you have multiple versions of
Python installed.


I adopted that practice years ago on Linux as well after wasting what
seemed like most of a day trying to figure out problems which turned
out to be caused by the fact that "pip" and "python" invoked different
versions of Python.


Although you still need to be aware that there might be a different 
Python installation between e.g. "python3 -m pip" and "python3.11 -m 
pip", etc. depending on what's been installed.


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


Re: Configuring an object via a dictionary

2024-03-16 Thread Thomas Passin via Python-list

On 3/16/2024 8:12 AM, Roel Schroeven via Python-list wrote:

Barry via Python-list schreef op 16/03/2024 om 9:15:


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

Me too. It's just too fragile. When writing code you're going to need an 
alternative for cases where "config.get('source_name') or default_value" 
doesn't work correctly; much better to use that alternative for all cases.


Trying to remember when I've used it, that was probably on personal code 
where I had a good idea what the values could be. Otherwise, I'm in 
agreement.


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


Re: Configuring an object via a dictionary

2024-03-15 Thread Thomas Passin via Python-list

On 3/15/2024 5:33 PM, Dan Sommers via Python-list wrote:

On 2024-03-15 at 15:48:17 -0400,
Thomas Passin via Python-list  wrote:


[...] And I suppose there is always the possibility that sometime in
the future an "or" clause like that will be changed to return a
Boolean, which one would expect anyway.


Not only is the current value is way more useful, but changing it would
be a compatibility and maintenance nightmare.


I'm with you here!


If I want Java, I know where to find it.  :-)


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


Re: Configuring an object via a dictionary

2024-03-15 Thread Thomas Passin via Python-list

On 3/15/2024 3:09 PM, Grant Edwards via Python-list wrote:

On 2024-03-15, Thomas Passin via Python-list  wrote:

On 3/15/2024 5:30 AM, 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?

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.

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?

Or should I be doing this completely differently?


  self.source_name = config.get('source_name', default_value)

Or, if you like this kind of expression better,

  self.source_name = config.get('source_name') or default_value


Won't the latter version misbehave if the value of config['source_name'] has a
"false" boolean value (e.g. "", 0, 0.0, None, [], (), {}, ...)


config = {}
config['source_name'] = ""
config.get('source_name') or 'default'

'default'


Oh, well, picky, picky!  I've always like writing using the "or" form 
and have never gotten bit - especially for configuration-type values 
where you really do expect a non-falsey value, it's probably low risk - 
but of course, you're right. In newer code I have been putting a default 
into get().  And I suppose there is always the possibility that sometime 
in the future an "or" clause like that will be changed to return a 
Boolean, which one would expect anyway.


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


Re: Configuring an object via a dictionary

2024-03-15 Thread Thomas Passin via Python-list

On 3/15/2024 5:30 AM, 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?

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.

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?

Or should I be doing this completely differently?


self.source_name = config.get('source_name', default_value)

Or, if you like this kind of expression better,

self.source_name = config.get('source_name') or default_value

.get() will return None if the key doesn't exist, or the default value 
if you specify one.

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


Re: pathlib.Path.is_file vs os.path.isfile difference

2024-03-10 Thread Thomas Passin via Python-list

On 3/10/2024 9:33 AM, Albert-Jan Roskam wrote:



On Mar 10, 2024 12:59, Thomas Passin via Python-list 
 wrote:


On 3/10/2024 6:17 AM, Barry wrote:
 >
 >
 >> On 8 Mar 2024, at 23:19, Thomas Passin via Python-list
 wrote:
 >>
 >> We just learned a few posts back that it might be specific to
Linux; I ran it on Windows.
 >
 > Depending on the exact win32 api used there is a 257 limit on
windows.
 > The 257 includes 2 for the device, C:, and 255 for the path part
that will use 1 for the leading \. Getting an error for a name that
is 255 is not surprising.
 >
 > Other api allow for 65535 limit, not sure on its additional limits.

I seem to remember there is a setting to allow longer paths, but I
forget any details.



=

You mean the "\\?\" prefix?

https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry


That and there's a registry setting:

https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation



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


Re: pathlib.Path.is_file vs os.path.isfile difference

2024-03-10 Thread Thomas Passin via Python-list

On 3/10/2024 6:17 AM, Barry wrote:




On 8 Mar 2024, at 23:19, Thomas Passin via Python-list  
wrote:

We just learned a few posts back that it might be specific to Linux; I ran it 
on Windows.


Depending on the exact win32 api used there is a 257 limit on windows.
The 257 includes 2 for the device, C:, and 255 for the path part that will use 
1 for the leading \. Getting an error for a name that is 255 is not surprising.

Other api allow for 65535 limit, not sure on its additional limits.


I seem to remember there is a setting to allow longer paths, but I 
forget any details.


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


Re: pathlib.Path.is_file vs os.path.isfile difference

2024-03-08 Thread Thomas Passin via Python-list

On 3/8/2024 5:14 PM, Albert-Jan Roskam wrote:



On Mar 8, 2024 19:35, Thomas Passin via Python-list 
 wrote:


On 3/8/2024 1:03 PM, Albert-Jan Roskam via Python-list wrote:
 > Hi,
 > I was replacing some os.path stuff with Pathlib and I
discovered this:
 > Path(256 * "x").is_file()  # OSError
 > os.path.isfile(256 * "x")  # bool
 > Is this intended? Does pathlib try to resemble os.path as
closely as
 > possible?

You must have an very old version of Python.  I'm running 3.12.2 and it
returns False.  Either that or that path name exists and throws some
kind of unexpected exception.





Hi, I tested this with Python 3.8. Good to know that this was fixed!


We just learned a few posts back that it might be specific to Linux; I 
ran it on Windows.


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


Re: pathlib.Path.is_file vs os.path.isfile difference

2024-03-08 Thread Thomas Passin via Python-list

On 3/8/2024 2:21 PM, Grant Edwards via Python-list wrote:

On 2024-03-08, Thomas Passin via Python-list  wrote:

On 3/8/2024 1:03 PM, Albert-Jan Roskam via Python-list wrote:

 Hi,
 I was replacing some os.path stuff with Pathlib and I discovered this:
 Path(256 * "x").is_file()  # OSError
 os.path.isfile(256 * "x")  # bool
 Is this intended? Does pathlib try to resemble os.path as closely as
 possible?


You must have an very old version of Python.  I'm running 3.12.2 and it
returns False.


It throws OSError with Python 3.11.8 on Linux.


Sorry, I should have said on Windows.



$ python
Python 3.11.8 (main, Feb 23 2024, 16:11:29) [GCC 13.2.1 20240113] on linux
Type "help", "copyright", "credits" or "license" for more information.

import pathlib
pathlib.Path(256 * "x").is_file()

Traceback (most recent call last):
   File "", line 1, in 
   File "/usr/lib/python3.11/pathlib.py", line 1267, in is_file
 return S_ISREG(self.stat().st_mode)
^^^
   File "/usr/lib/python3.11/pathlib.py", line 1013, in stat
 return os.stat(self, follow_symlinks=follow_symlinks)
^^
OSError: [Errno 36] File name too long: 
''


import os
os.path.isfile(256 * "x")

False



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


Re: pathlib.Path.is_file vs os.path.isfile difference

2024-03-08 Thread Thomas Passin via Python-list

On 3/8/2024 1:03 PM, Albert-Jan Roskam via Python-list wrote:

Hi,
I was replacing some os.path stuff with Pathlib and I discovered this:
Path(256 * "x").is_file()  # OSError
os.path.isfile(256 * "x")  # bool
Is this intended? Does pathlib try to resemble os.path as closely as
possible?


You must have an very old version of Python.  I'm running 3.12.2 and it 
returns False.  Either that or that path name exists and throws some 
kind of unexpected exception.


The Python docs say

"Return True if the path points to a regular file (or a symbolic link 
pointing to a regular file), False if it points to another kind of file.


False is also returned if the path doesn’t exist or is a broken symlink; 
other errors (such as permission errors) are propagated"

--
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 Thomas Passin via Python-list

On 3/6/2024 7:55 AM, Jacob Kruger via Python-list wrote:
Ok, simpler version - all the code in a simpler test file, and working 
with two separate variables to explain exactly what am talking about:


# start code

from datetime import datetime, timezone, timedelta

from copy import copy


# initialise original values

dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d 
%H:%M").replace(tzinfo=timezone.utc)


l_test = [1, 2, 3]


def do_it():
     global dt_expiry, l_test # asked python to refer to global 
variables for both


     # assign new value immediately

     dt_expiry = datetime.now()+timedelta(minutes=5)
     print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new 
value has been assigned

     # grab copy of list for re-use of items
     l_temp = copy(l_test)
     # following line means l_test will later on retain value in global 
scope because it was manipulated inside function instead of just 
assigned new value

     l_test.clear()
     # replace original set of values
     for i in l_temp: l_test.append(i)
     # add new item
     l_test.append(99)
# end of do_it function

# end code


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check the 
value of the dt_expiry variable afterwards, it's reverted to the 1970... 
value?


Not when I run your code. With a little annotation added to the print 
statements I get (I added the import statements to make it run, and I 
used the same date-time formatting for all three print statements):


List before: [1, 2, 3]
start: 1970-01-01 00:00
inside after reassignment: 2024-03-06 08:57
outside after: 2024-03-06 08:57
List after: [1, 2, 3, 99]

As an aside, you have gone to some trouble to copy, clear, and 
reconstruct l_test.  It would be simpler like this (and you wouldn't 
have to import the "copy" library):


l_temp = l_test[:]
l_test = []

Instead of those lines and then this:

for i in l_temp: l_test.append(i)

you could achieve the same thing with this single statement:

l_test = l_test[:]


If I take out the line that removes values from l_test # l_test.clear() 
# before appending new value to it, then it will also not retain it's 
new/additional child items after the function exits, and will just 
revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling purely 
content retrieval functions against said objects, or assigning them new 
values from scratch seems to then ignore the global scope specified in 
the first line inside the function?



Hope this makes more sense


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


On 2024/03/05 20:23, dn via Python-list wrote:

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 t

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

2024-03-06 Thread Thomas Passin via Python-list

On 3/6/2024 5:59 AM, Alan Gauld via Python-list wrote:

On 05/03/2024 22:46, Grant Edwards via Python-list wrote:

Unfortunately (presumably thanks to SEO) the enshittification of
Google has reached the point where searching for info on things like
Python name scope, the first page of links are to worthless sites like
geeksforgeeks.

And not just Google, I just tried bing, yahoo and duckduckgo
and they are all the same. Not a one listed anything from
python.org on the first page... In fact it didn't even appear
in the first 100 listings, although wikipedia did manage an
entry, eventually.


I don't know ... I just searched for "python local vs global variables" 
and a python.org page on it was the second hit. I usually use StartPage 
- who knows where they aggregate from - but the same search on Google 
and Bing also popped up the python.org link as the second hit.  As usual 
Bing was a nasty experience, though.


Still, if your search phrase isn't as well focused as that or you are 
less lucky, for sure you'll get all sorts of junk.


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


Re: Problem resizing a window and button placement

2024-02-26 Thread Thomas Passin via Python-list

On 2/26/2024 6:02 AM, Steve GS via Python-list wrote:

Although your code produces the value of Ww outside the function, I do not see 
how I can use the value of Ww unless I close the program.


The configuration event hasn't fired at the time you include the print 
statement in the handler's def block, and therefore the print function 
inside your handler hasn't invoked.  It won't be invoked until you 
resize the window.


There is no point to saving the width and height outside your 
on_configure() function, because outside that function you can't know if 
they have been changed.  There could even have been a race condition 
where you use one but the other changes before you get around to using 
it.  It's better just to ask tk for the values whenever you need them, 
as you do inside your handler.



import tkinter as tk

Ww = None  # What does this do? Why not Integer?
WwZ = None

# These could be integers, like 0, but that would not be the correct
# window sizes at that point. The window is either not constructed or it
# has some definite size that is not zero.


def on_configure(*args):
 global Ww
 global WwZ
 Ww = root.winfo_width()
 print("9  Ww Inside =<"+str(Ww)+">")  # works
 WwZ = Ww * 2
 print("11  WwZ Inside =<"+str(WwZ)+">")  # works
 return(Ww)  #Can I use this?
 
root = tk.Tk()

root.bind('',on_configure)
print("15  Ww Inside1 = <"+str(Ww)+">")
#Ww2 = int(Ww) * 2  # fails
print("17  WwZ Inside2 = <"+str(WwZ)+">")

root.mainloop()

Ww2 = int(Ww) * 2  #Works but only after the program stops
print("21  Ww Outside2 = <"+str(WwZ)+">")
# Can I have concentric loops?


SGA

-Original Message-
From: Alan Gauld 
Sent: Monday, February 26, 2024 4:04 AM
To: Steve GS ; python-list@python.org
Subject: Re: RE: Problem resizing a window and button placement

On 26/02/2024 07:56, Steve GS via Python-list wrote:


Then there is that discovery
element: Why is my original
idea not working? I still
cannot pass the value back
from the function.  What is
different about this function
that others would have given
me the value?


There is nothing different, see the code below.
print() is a function like any other.
In this case it is called after you close the window, ie after mainloop() exits.
But any other function called inside
mainloop - eg any other event handler can also access it.

For example, if you added a button:

def printW(): print("Button Ww = ", Ww)

bw = tk.Button(root, text="Print Width", command=printW)
bw.pack()

You would be able to print the value on demand.


import tkinter as tk

Ww = None

def on_configure(*args):
 global Ww
 Ww = root.winfo_width()
 print("Ww Inside =<"+str(Ww)+">")

root = tk.Tk()
root.bind('',on_configure)
root.mainloop()

print("Ww Outside = <"+str(Ww)+">")


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




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


Re: Problem resizing a window and button placement

2024-02-25 Thread Thomas Passin via Python-list

On 2/25/2024 4:19 PM, Steve GS via Python-list wrote:

SOLUTION FOUND!

The fix was to write the code that uses the width value and to place it into 
the function itself.
Kluge? Maybe but it works.


Right, just what I wrote earlier:

"have the function that responds to the resize event perform the action 
that you want"



Mischief Managed.


As for the most recent suggestion, it fails for me:

Traceback (most recent call last):
   File "F:/___zInsulin Code A 08-02-23/WinPic/IOWw.pyw", line 14, in 
 print("Ww Outside = <" + str(Ww) > + ">")
TypeError: bad operand type for unary +: 'str'

With the need to close the window, it adds an extra step and intervention to 
the program to use. I am not sure how this help[s.

As a curio, it would be interesting to see how to use the value of a variable, 
created in the function used here, and make it available to the code outside 
the function.



SGA

-Original Message-
From: Alan Gauld 
Sent: Sunday, February 25, 2024 12:44 PM
To: Steve GS ; python-list@python.org
Subject: Re: RE: Problem resizing a window and button placement

On 25/02/2024 03:58, Steve GS via Python-list wrote:
import tkinter as tk

Ww = None

def on_configure(*args):
global Ww
Ww = root.winfo_width()
print("Ww Inside = <" + str(Ww) + ">")

root = tk.Tk()
root.bind('', on_configure)
root.mainloop()

print("Ww Outside = <" + str(Ww) > + ">")

Produces:
Ww Inside = <200>
Ww Inside = <200>
Ww Inside = <205>
Ww Inside = <205>
Ww Inside = <206>
Ww Inside = <206>
Ww Outside = <206>

HTH



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


Re: Problem resizing a window and button placement

2024-02-24 Thread Thomas Passin via Python-list

On 2/24/2024 9:51 PM, Steve GS via Python-list wrote:
First of all, please make sure that the formatting is readable and 
especially the indentation.  This is Python, after all.


Do not use tabs; use 3 or 4 spaces instead of each tab.

import tkinter as tk

#global Ww  Neither global
helps
def on_configure(*args):
# print(args)
  #global Ww  Neither
global helps
  Ww = root.winfo_width()
  print("WwInside = <" +
str(Ww) + ">")

root = tk.Tk()
root.bind('',
on_configure)
print("WwOutside = <" +
str(Ww) + ">")
#NameError: name 'Ww' is not
defined


The function that declares Ww hasn't run yet. As I wrote earlier, the 
function bound to the callback should do all the work for the callback, 
or it should call other functions that do.  That's if you don't let a 
layout do it all for you, as others have written.



root.mainloop()

SGA

-Original Message-
From: Python-list
 On
Behalf Of MRAB via Python-list
Sent: Saturday, February 24,
2024 7:49 PM
To: python-list@python.org
Subject: Re: Problem resizing
a window and button placement

On 2024-02-25 00:33, Steve GS
via Python-list wrote:

"Well, yes, in Python a
variable created inside a
function or method is local

to

that function unless you
declare it global."

Yes, I knew that. I tried to
global it both before the
function call and within it.
Same for when I created the
variable. If I try to use it
in the rest of the code, it
keeps coming up as not
declared.  In other

functions,

I can 'return' the variable
but that apparently would

not

work for this function.

Is this type of function any
different that that which I
have been using?


Please post a short example
that shows the problem.



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


Re: Problem resizing a window and button placement

2024-02-24 Thread Thomas Passin via Python-list

On 2/24/2024 3:20 AM, Steve GS via Python-list wrote:

Yes, I ran that elegantly
simple code. The print
statement reports the X, Y,
Height and Width values.
However, I do not see how to
capture the width value.

  I experimented with the code
Vwidth = rootV.winfo_width()
and it also reports the width
as I resize the window.

However, I cannot seem to use
the variable Vwidth outside
the sub routine. It is acting
as if Vwidth is not global but
I added that.  It is reported
that Vwidth is not defined
when I try to use it in my
code.


Well, yes, in Python a variable created inside a function or method is 
local to that function unless you declare it global. That characteristic 
is called its "scope". But if you think you need it to be a global 
variable you should rethink your design. For one thing, before the next 
time you use your global variable the window size may have changed again.


Instead, it would be better to have the function that responds to the 
resize event perform the action that you want, or call another function 
that does, passing the new width to it.


Note that in most programming languages, variables have a scope.  The 
rules about those scopes vary between languages.




So close..
SGA

-Original Message-
From: Barry

Sent: Saturday, February 24,
2024 3:04 AM
To: Steve GS

Cc: MRAB
;
python-list@python.org
Subject: Re: Problem resizing
a window and button placement




On 24 Feb 2024, at 04:36,

Steve GS via Python-list

wrote:


How do I extract the values
from args?


You can look up the args in
documentation.
You can run the example code
MRAB provided and see what is
printed to learn what is in
the args.

Barry




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


Re: Testing (sorry)

2024-02-19 Thread Thomas Passin via Python-list

On 2/19/2024 11:55 AM, Skip Montanaro wrote:

Here is a typical bounce message that I get:

mailto:python-list@python.org>>: host
mail.python.org [188.166.95.178] said:
450-4.3.2
      Service currently unavailable 450 4.3.2

Some time after I get one of these messages I re-send the post. 
Usually

it gets through then.


Looks kinda like greylisting to me. I'm pretty sure that's one of the 
tool in the mail.python.org  chain.


I don't see it as greylisting.  A repeat post will succeed, before there 
would be time for my email provider (Dreamhost) to do anything about it.


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


Re: Testing (sorry)

2024-02-19 Thread Thomas Passin via Python-list

On 2/19/2024 9:17 AM, Grant Edwards via Python-list wrote:

On 2024-02-19, Thomas Passin  wrote:


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


Sometimes a post of mine will not show up for hours or even half a day.
They are all addressed directly to the list.  Sometimes my email
provider sends me a notice that the message bounced.  Those notices say
that the address wasn't available when the transmission was tried.


Here is a typical bounce message that I get:

: host mail.python.org[188.166.95.178] said: 
450-4.3.2

Service currently unavailable 450 4.3.2

Some time after I get one of these messages I re-send the post.  Usually 
it gets through then.



I guess that in future I'll wait a couple days before I assume
something is broken.

--
Grant



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


Re: Testing (sorry)

2024-02-18 Thread Thomas Passin via Python-list

On 2/18/2024 6:09 PM, Grant Edwards via Python-list wrote:

On 2024-02-18, Peter J. Holzer via Python-list  wrote:

[Replying to the list *and* Grant]

On 2024-02-17 19:38:04 -0500, Grant Edwards via Python-list wrote:

Today I noticed that nothing I've posted to python-list in past 3
weeks has shown up on the list.


January 29th, AFAICS. And end of december before that.


I don't know how to troubleshoot this other than sending test
messages.  Obviously, if this shows up on the list, then I've gotten
it to work...


This did show up and 3 other test messages with very similar text
as well.

Also there was a whole flurry of almost but not quite identical messages
from you in the "nan" thread.


Sorry about that.

All of those were posted at various times throughout the day yesterday
using two different accounts, two different mail servers, and three
different methods for submitting the e-mails.  I finally gave up and
switched to using comp.lang.python via Usenet.

Then, about 24 hours later, all those messages finally showed up.

At one point about half way through that process yesterday, I
unsusbscribed and then re-subscribed both e-mail addresses.  I got
confirmation and welcome messages on both accounts.  Sending "help"
requests to the list server produced the expected results. I enabled
the sending of confirmation messages from the list server.

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


Sometimes a post of mine will not show up for hours or even half a day. 
They are all addressed directly to the list.  Sometimes my email 
provider sends me a notice that the message bounced.  Those notices say 
that the address wasn't available when the transmission was tried.


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


Re: Extract lines from file, add to new files

2024-02-03 Thread Thomas Passin via Python-list

On 2/3/2024 5:02 PM, dn via Python-list wrote:
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)


Pairs programming can be fun and productive, if you are lucky to have 
the right person to work with.  I've had one person like that over the 
years.


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 joi

Re: Extract lines from file, add to new files

2024-02-03 Thread Thomas Passin via Python-list
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.


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.


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.


On 2/3/2024 11:33 AM, avi.e.gr...@gmail.com wrote:

Thomas,

I have been thinking about the concept of being stingy with information as
this is a fairly common occurrence when people ask for help. They often ask
for what they think they want while people like us keep asking why they want
that and perhaps offer guidance on how to get closer to what they NEED or a
better way.

In retrospect, Rich did give all the info he thought he needed. It boiled
down to saying that he wants to distribute data into two files in such a way
that finding an item in file A then lets him find the corresponding item in
file B. He was not worried about how to make the files or what to do with
the info afterward. He had those covered and was missing what he considered
a central piece. And, it seems he programs in multiple languages and
environments as needed and is not exactly a newbie. He just wanted a way to
implement his overall design.

We threw many solutions and ideas at him but some of us (like me) also got
frustrated as some ideas were not received due to one objection or another
that had not been mentioned earlier when it was not seen as important.

I particularly notice a disconnect some of us had. Was this supposed to be a
search that read only as much as needed to find something and stopped
reading, or a sort of filter that returned zero or more matches and went to
the end, or perhaps something that read entire files and swallowed them into
data structures in memory and then searched and found corresponding entries,
or maybe something else?

All the above approaches could work but some designs not so much. For
example, some files are too large. We, as programmers, often consciously or
unconsciously look at many factors to try to zoom in on what approaches me
might use. To be given minimal amounts of info can be frustrating. We worry
about making a silly design. But the OP may want something minimal and not
worry as long as it is fairly easy to program and works.

We could have suggested something very simple like:

Open both files A and B
In a loop get a line from each. If the line from A is a match, do something
with the current line from B.
If you are getting only one, exit the loop.

Or, if willing, we could have suggested any other file format, such as a
CSV, in which the algorithm is similar but different as in:

Open file A
Read a line in a loop
Split it in parts
If the party of the first part matches something, use the party of the
second part

Or, of course, suggest they read the entire file, into a list of lines or a
data.frame and use some tools that search all of it and produce results.

I find I personally now often lean toward the latter approach but ages ago
when memory and CPU were considerations and maybe garbage collection was not
automatic, ...


-Original Message-
From: Python-list  On
Behalf Of Thomas Passin via Python-list
Sent: Wednesday, January 31, 2024 7:25 AM
To: python-list@python.org
Subject: Re: Extract lines from file, add to new files

On 1/30/2024 11:25 PM, avi.e.gr...@gmail.com wrote:

Thomas, on some points we may see it differently.


I'm mostly going by what the OP originally asked for back on Jan 11.
He's been too stingy with information since then to be worth spending
much time on, IMHO.


Some formats can be done simply but are maybe be

Re: Extract lines from file, add to new files

2024-01-31 Thread Thomas Passin via Python-list

On 1/31/2024 9:05 AM, Rich Shepard via Python-list wrote:

On Tue, 30 Jan 2024, Thomas Passin via Python-list wrote:


If I had a script that's been working for 30 years, I'd probably just use
Python to do the personalizing and let the rest of the bash script do the
rest, like it always has. The Python program would pipe or send the
personalized messages to the rest of the bash program. Something in that
ballpark, anyway.


Thomas,

A bash shell script looks easier for me and more promising. Using a while
loop (one for the name file the other for the address file), and sed for
putting the name at the head of the message replacing a generic placeholder
should work with the existing for loop script.


Sounds good.  I'd still be a bit worried about the two files getting out 
of sync, as others have mentioned.


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


Re: Extract lines from file, add to new files

2024-01-31 Thread Thomas Passin via Python-list

On 1/30/2024 11:25 PM, avi.e.gr...@gmail.com wrote:

Thomas, on some points we may see it differently.


I'm mostly going by what the OP originally asked for back on Jan 11. 
He's been too stingy with information since then to be worth spending 
much time on, IMHO.



Some formats can be done simply but are maybe better done in somewhat
standard ways.

Some of what the OP has is already tables in a database and that can
trivially be exported into a CSV file or other formats like your TSV file
and more. They can also import from there. As I mentioned, many spreadsheets
and all kinds of statistical programs tend to support some formats making it
quite flexible.

Python has all kinds of functionality, such as in the pandas module, to read
in a CSV or write it out. And once you have the data structure in memory, al
kinds of queries and changes can be made fairly straightforwardly. As one
example, Rich has mentioned wanting finer control in selecting who gets some
version of the email based on concepts like market segmentation. He already
may have info like the STATE (as in Arizona) in his database. He might at
some point enlarge his schema so each entry is placed in one or more
categories and thus his CSV, once imported, can do the usual tasks of
selecting various rows and columns or doing joins or whatever.

Mind you, another architecture could place quite a bit of work completely on
the back end and he could send SQL queries to the database from python and
get back his results into python which would then make the email messages
and pass them on to other functionality to deliver. This would remove any
need for files and just rely on the DB.

There as as usual, too many choices and not necessarily one best answer. Of
course if this was a major product that would be heavily used, sure, you
could tweak and optimize. As it is, Rich is getting a chance to improve his
python skills no matter which way he goes.



-Original Message-
From: Python-list  On
Behalf Of Thomas Passin via Python-list
Sent: Tuesday, January 30, 2024 10:37 PM
To: python-list@python.org
Subject: Re: Extract lines from file, add to new files

On 1/30/2024 12:21 PM, Rich Shepard via Python-list wrote:

On Tue, 30 Jan 2024, Thomas Passin via Python-list wrote:


Fine, my toy example will still be applicable. But, you know, you haven't
told us enough to give you help. Do you want to replace text from values
in a file? That's been covered. Do you want to send the messages using
those libraries? You haven't said what you don't know how to do.
Something
else? What is it that you want to do that you don't know how?


Thomas,

For 30 years I've used a bash script using mailx to send messages to a

list

of recipients. They have no salutation to personalize each one. Since I
want
to add that personalized salutation I decided to write a python script to
replace the bash script.

I have collected 11 docs explaining the smtplib and email modules and
providing example scripts to apply them to send multiple individual
messages
with salutations and attachments.


If I had a script that's been working for 30 years, I'd probably just
use Python to do the personalizing and let the rest of the bash script
do the rest, like it always has.  The Python program would pipe or send
the personalized messages to the rest of the bash program. Something in
that ballpark, anyway.


Today I'm going to be reading these. They each recommend using .csv input
files for names and addresses. My first search is learning whether I can
write a single .csv file such as:
"name1","address1"
"mane2","address2"
which I believe will work; and by inserting at the top of the message

block

Hi, {yourname}
the name in the .csv file will replace the bracketed place holder

If the file contents are going to be people's names and email addresses,
I would just tab separate them and split each line on the tab.  Names
aren't going to include tabs so that would be safe.  Email addresses
might theoretically include a tab inside a quoted name but that would be
extremely obscure and unlikely.  No need for CSV, it would just add
complexity.

data = f.readlines()
for d in data:
  name, addr = line.split('\t') if line.strip() else ('', '')


Still much to learn and the batch of downloaded PDF files should educate
me.

Regards,

Rich




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


Re: Extract lines from file, add to new files

2024-01-30 Thread Thomas Passin via Python-list

On 1/30/2024 12:21 PM, Rich Shepard via Python-list wrote:

On Tue, 30 Jan 2024, Thomas Passin via Python-list wrote:


Fine, my toy example will still be applicable. But, you know, you haven't
told us enough to give you help. Do you want to replace text from values
in a file? That's been covered. Do you want to send the messages using
those libraries? You haven't said what you don't know how to do. 
Something

else? What is it that you want to do that you don't know how?


Thomas,

For 30 years I've used a bash script using mailx to send messages to a list
of recipients. They have no salutation to personalize each one. Since I 
want

to add that personalized salutation I decided to write a python script to
replace the bash script.

I have collected 11 docs explaining the smtplib and email modules and
providing example scripts to apply them to send multiple individual 
messages

with salutations and attachments.


If I had a script that's been working for 30 years, I'd probably just 
use Python to do the personalizing and let the rest of the bash script 
do the rest, like it always has.  The Python program would pipe or send 
the personalized messages to the rest of the bash program. Something in 
that ballpark, anyway.



Today I'm going to be reading these. They each recommend using .csv input
files for names and addresses. My first search is learning whether I can
write a single .csv file such as:
"name1","address1"
"mane2","address2"
which I believe will work; and by inserting at the top of the message block
Hi, {yourname}
the name in the .csv file will replace the bracketed place holder
If the file contents are going to be people's names and email addresses, 
I would just tab separate them and split each line on the tab.  Names 
aren't going to include tabs so that would be safe.  Email addresses 
might theoretically include a tab inside a quoted name but that would be 
extremely obscure and unlikely.  No need for CSV, it would just add 
complexity.


data = f.readlines()
for d in data:
name, addr = line.split('\t') if line.strip() else ('', '')

Still much to learn and the batch of downloaded PDF files should educate 
me.


Regards,

Rich


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


Re: Extract lines from file, add to new files

2024-01-30 Thread Thomas Passin via Python-list

On 1/30/2024 8:37 AM, Rich Shepard via Python-list wrote:

On Mon, 29 Jan 2024, Thomas Passin via Python-list wrote:


If you aren't going to use one or another existing template system,
perhaps the easiest is to use unique strings in the message file. For
example:

Dear __##so-and-so##__:
  Please don't write this message off as mere spam.
  Respectfully, Rich

Then you just do a replace of the unique string by the salutation. Don't
change the original (i.e., template), make the changes to a copy that you
will output.


My script is not a web application, but an emailer that allows me to 
contact

clients and prospective clients. From the command line on a linux host.
Using the python smtplib and mail modules.

Rich


Fine, my toy example will still be applicable.  But, you know, you 
haven't told us enough to give you help.  Do you want to replace text 
from values in a file?  That's been covered. Do you want to send the 
messages using those libraries?  You haven't said what you don't know 
how to do.  Something else? What is it that you want to do that you 
don't know how?


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


Re: Extract lines from file, add to new files

2024-01-29 Thread Thomas Passin via Python-list

On 1/29/2024 11:15 AM, 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. :-)

TIA,

Rich


I'm assuming this is a continuation of a previous thread about working 
with alternate lines with salutation and address, and I assume you've 
got that worked out.


If you aren't going to use one or another existing template system, 
perhaps the easiest is to use unique strings in the message file.  For 
example:


Dear __##so-and-so##__:
   Please don't write this message off as mere spam.
   Respectfully, Rich

Then you just do a replace of the unique string by the salutation. Don't 
change the original (i.e., template), make the changes to a copy that 
you will output.


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


Re: How to replace a cell value with each of its contour cells and yield the corresponding datasets seperately in a list according to a Pandas-way?

2024-01-21 Thread Thomas Passin via Python-list

On 1/21/2024 1:25 PM, marc nicole wrote:
It is part of a larger project aiming at processing data according to a 
given algorithm

Do you have any comments or any enhancing recommendations on the code?


I'm not knowledgeable enough about either pandas or numpy, I'm afraid, 
just very basic usage.  Someone else will probably pitch in.



Thanks.

Le dim. 21 janv. 2024 à 18:28, Thomas Passin via Python-list 
mailto:python-list@python.org>> a écrit :


On 1/21/2024 11:54 AM, marc nicole wrote:
 > Thanks for the reply,
 >
 > I think using a Pandas (or a Numpy) approach would optimize the
 > execution of the program.
 >
 > Target cells could be up to 10% the size of the dataset, a good
example
 > to start with would have from 10 to 100 values.

Thanks for the reformatted code.  It's much easier to read and think
about.

For say 100 points, it doesn't seem that "optimization" would be
much of
an issue.  On my laptop machine and Python 3.12, your example takes
around 5 seconds to run and print().  OTOH if you think you will go to
much larger datasets, certainly execution time could become a factor.

I would think that NumPy arrays and/or matrices would have good
potential.

Is this some kind of a cellular automaton, or an image filtering
process?

 > Let me know your thoughts, here's a reproducible example which I
formatted:
 >
 >
 >
 > from numpy import random
 > import pandas as pd
 > import numpy as np
 > import operator
 > import math
 > from collections import deque
 > from queue import *
 > from queue import Queue
 > from itertools import product
 >
 >
 > def select_target_values(dataframe, number_of_target_values):
 >      target_cells = []
 >      for _ in range(number_of_target_values):
 >          row_x = random.randint(0, len(dataframe.columns) - 1)
 >          col_y = random.randint(0, len(dataframe) - 1)
 >          target_cells.append((row_x, col_y))
 >      return target_cells
 >
 >
 > def select_contours(target_cells):
 >      contour_coordinates = [(0, 1), (1, 0), (0, -1), (-1, 0)]
 >      contour_cells = []
 >      for target_cell in target_cells:
 >          # random contour count for each cell
 >          contour_cells_count = random.randint(1, 4)
 >          try:
 >              contour_cells.append(
 >                  [
 >                      tuple(
 >                          map(
 >                              lambda i, j: i + j,
 >                              (target_cell[0], target_cell[1]),
 >                              contour_coordinates[iteration_],
 >                          )
 >                      )
 >                      for iteration_ in range(contour_cells_count)
 >                  ]
 >              )
 >          except IndexError:
 >              continue
 >      return contour_cells
 >
 >
 > def create_zipf_distribution():
 >      zipf_dist = random.zipf(2, size=(50, 5)).reshape((50, 5))
 >
 >      zipf_distribution_dataset = pd.DataFrame(zipf_dist).round(3)
 >
 >      return zipf_distribution_dataset
 >
 >
 > def apply_contours(target_cells, contour_cells):
 >      target_cells_with_contour = []
 >      # create one single list of cells
 >      for idx, target_cell in enumerate(target_cells):
 >          target_cell_with_contour = [target_cell]
 >          target_cell_with_contour.extend(contour_cells[idx])
 >          target_cells_with_contour.append(target_cell_with_contour)
 >      return target_cells_with_contour
 >
 >
 > def create_possible_datasets(dataframe, target_cells_with_contour):
 >      all_datasets_final = []
 >      dataframe_original = dataframe.copy()
 >
 >      list_tuples_idx_cells_all_datasets = list(
 >          filter(
 >              lambda x: x,
 >              [list(tuples) for tuples in
 > list(product(*target_cells_with_contour))],
 >          )
 >      )
 >      target_original_cells_coordinates = list(
 >          map(
 >              lambda x: x[0],
 >              [
 >                  target_and_contour_cell
 >                  for target_and_contour_cell in
target_cells_with_contour
 >              ],
 >          )
 >      )
 >      for dataset_index_values in list_tuples_idx_cells_all_datasets:
 >          all_datasets = []
 >          for 

Re: How to replace a cell value with each of its contour cells and yield the corresponding datasets seperately in a list according to a Pandas-way?

2024-01-21 Thread Thomas Passin via Python-list

On 1/21/2024 11:54 AM, marc nicole wrote:

Thanks for the reply,

I think using a Pandas (or a Numpy) approach would optimize the 
execution of the program.


Target cells could be up to 10% the size of the dataset, a good example 
to start with would have from 10 to 100 values.


Thanks for the reformatted code.  It's much easier to read and think about.

For say 100 points, it doesn't seem that "optimization" would be much of 
an issue.  On my laptop machine and Python 3.12, your example takes 
around 5 seconds to run and print().  OTOH if you think you will go to 
much larger datasets, certainly execution time could become a factor.


I would think that NumPy arrays and/or matrices would have good potential.

Is this some kind of a cellular automaton, or an image filtering process?


Let me know your thoughts, here's a reproducible example which I formatted:



from numpy import random
import pandas as pd
import numpy as np
import operator
import math
from collections import deque
from queue import *
from queue import Queue
from itertools import product


def select_target_values(dataframe, number_of_target_values):
     target_cells = []
     for _ in range(number_of_target_values):
         row_x = random.randint(0, len(dataframe.columns) - 1)
         col_y = random.randint(0, len(dataframe) - 1)
         target_cells.append((row_x, col_y))
     return target_cells


def select_contours(target_cells):
     contour_coordinates = [(0, 1), (1, 0), (0, -1), (-1, 0)]
     contour_cells = []
     for target_cell in target_cells:
         # random contour count for each cell
         contour_cells_count = random.randint(1, 4)
         try:
             contour_cells.append(
                 [
                     tuple(
                         map(
                             lambda i, j: i + j,
                             (target_cell[0], target_cell[1]),
                             contour_coordinates[iteration_],
                         )
                     )
                     for iteration_ in range(contour_cells_count)
                 ]
             )
         except IndexError:
             continue
     return contour_cells


def create_zipf_distribution():
     zipf_dist = random.zipf(2, size=(50, 5)).reshape((50, 5))

     zipf_distribution_dataset = pd.DataFrame(zipf_dist).round(3)

     return zipf_distribution_dataset


def apply_contours(target_cells, contour_cells):
     target_cells_with_contour = []
     # create one single list of cells
     for idx, target_cell in enumerate(target_cells):
         target_cell_with_contour = [target_cell]
         target_cell_with_contour.extend(contour_cells[idx])
         target_cells_with_contour.append(target_cell_with_contour)
     return target_cells_with_contour


def create_possible_datasets(dataframe, target_cells_with_contour):
     all_datasets_final = []
     dataframe_original = dataframe.copy()

     list_tuples_idx_cells_all_datasets = list(
         filter(
             lambda x: x,
             [list(tuples) for tuples in 
list(product(*target_cells_with_contour))],

         )
     )
     target_original_cells_coordinates = list(
         map(
             lambda x: x[0],
             [
                 target_and_contour_cell
                 for target_and_contour_cell in target_cells_with_contour
             ],
         )
     )
     for dataset_index_values in list_tuples_idx_cells_all_datasets:
         all_datasets = []
         for idx_cell in range(len(dataset_index_values)):
             dataframe_cpy = dataframe.copy()
             dataframe_cpy.iat[
                 target_original_cells_coordinates[idx_cell][1],
                 target_original_cells_coordinates[idx_cell][0],
             ] = dataframe_original.iloc[
                 dataset_index_values[idx_cell][1], 
dataset_index_values[idx_cell][0]

             ]
             all_datasets.append(dataframe_cpy)
         all_datasets_final.append(all_datasets)
     return all_datasets_final


def main():
     zipf_dataset = create_zipf_distribution()

     target_cells = select_target_values(zipf_dataset, 5)
     print(target_cells)
     contour_cells = select_contours(target_cells)
     print(contour_cells)
     target_cells_with_contour = apply_contours(target_cells, contour_cells)
     datasets = create_possible_datasets(zipf_dataset, 
target_cells_with_contour)

     print(datasets)


main()

Le dim. 21 janv. 2024 à 16:33, Thomas Passin via Python-list 
mailto:python-list@python.org>> a écrit :


On 1/21/2024 7:37 AM, marc nicole via Python-list wrote:
 > Hello,
 >
 > I have an initial dataframe with a random list of target cells
(each cell
 > being identified with a couple (x,y)).
 > I want to yield four different dataframes each containing the
value of one
 > of the contour (surrounding) cells of each specified target cell.
 >
 > the surrounding cells 

Re: How to replace a cell value with each of its contour cells and yield the corresponding datasets seperately in a list according to a Pandas-way?

2024-01-21 Thread Thomas Passin via Python-list

On 1/21/2024 7:37 AM, marc nicole via Python-list wrote:

Hello,

I have an initial dataframe with a random list of target cells (each cell
being identified with a couple (x,y)).
I want to yield four different dataframes each containing the value of one
of the contour (surrounding) cells of each specified target cell.

the surrounding cells to consider for a specific target cell are : (x-1,y),
(x,y-1),(x+1,y);(x,y+1), specifically I randomly choose 1 to 4 cells from
these and consider for replacement to the target cell.

I want to do that through a pandas-specific approach without having to
define the contour cells separately and then apply the changes on the
dataframe 


1. Why do you want a Pandas-specific approach?  Many people would rather 
keep code independent of special libraries if possible;


2. How big can these collections of target cells be, roughly speaking? 
The size could make a big difference in picking a design;


3. You really should work on formatting code for this list.  Your code 
below is very complex and would take a lot of work to reformat to the 
point where it is readable, especially with the nearly impenetrable 
arguments in some places.  Probably all that is needed is to replace all 
tabs by (say) three spaces, and to make sure you intentionally break 
lines well before they might get word-wrapped.  Here is one example I 
have reformatted (I hope I got this right):


list_tuples_idx_cells_all_datasets = list(filter(
   lambda x: utils_tuple_list_not_contain_nan(x),
   [list(tuples) for tuples in list(
 itertools.product(*target_cells_with_contour))
   ]))

4. As an aside, it doesn't look like you need to convert all those 
sequences and iterators to lists all over the place;




(but rather using an all in one approach):
for now I have written this example which I think is not Pandas specific:

[snip]

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


Re: Question about garbage collection

2024-01-16 Thread Thomas Passin via Python-list

On 1/16/2024 4:17 AM, Barry wrote:




On 16 Jan 2024, at 03:49, Thomas Passin via Python-list 
 wrote:

This kind of thing can happen with PyQt, also.  There are ways to minimize it 
but I don't know if you can ever be sure all Qt C++ objects will get deleted. 
It depends on the type of object and the circumstances.


When this has been seen in the past it has been promptly fixed by the 
maintainer.


The usual advice is to call deleteLater() on objects derived from PyQt 
classes.  I don't know enough about PyQt to know if this takes care of 
all dangling reference problems, though.


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-15 Thread Thomas Passin via Python-list

On 1/15/2024 7:24 PM, Thomas Passin wrote:

On 1/15/2024 6:27 PM, Greg Ewing via Python-list wrote:

On 16/01/24 11:55 am, Mats Wichmann wrote:
Windows natively has something called python.exe and python3.exe 
which is interfering here


I'm wondering whether py.exe should be taught to recognise these stubs
and ignore them. This sounds like something that could trip a lot of
people up.


There are registry entries that say where all the python.org install 
locations are.  I suppose, but don't know, that py.exe checks them.  The 
registry entries are 
in Computer\HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore


For python.org installs that are installed for all users, the entries are in

Computer\HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore

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


Re: Question about garbage collection

2024-01-15 Thread Thomas Passin via Python-list

On 1/15/2024 9:47 PM, Akkana Peck via Python-list wrote:

I wrote:

Also be warned that some modules (particularly if they're based on libraries 
not written in Python) might not garbage collect, so you may need to use other 
methods of cleaning up after those objects.


Chris Angelico writes:

Got any examples of that?


The big one for me was gdk-pixbuf, part of GTK. When you do something like 
gtk.gdk.pixbuf_new_from_file(), there's a Python object that gets created, but 
there's also the underlying C code that allocates memory for the pixbuf. When 
the object went out of scope, the Python object was automatically garbage 
collected, but the pixbuf data leaked.


This kind of thing can happen with PyQt, also.  There are ways to 
minimize it but I don't know if you can ever be sure all Qt C++ objects 
will get deleted. It depends on the type of object and the circumstances.



Calling gc.collect() caused the pixbuf data to be garbage collected too.

There used to be a post explaining this on the pygtk mailing list: the link was
http://www.daa.com.au/pipermail/pygtk/2003-December/006499.html
but that page is gone now and I can't seem to find any other archives of that 
list (it's not on archive.org either). And this was from GTK2; I never checked 
whether the extra gc.collect() is still necessary in GTK3, but I figure leaving 
it in doesn't hurt anything. I use pixbufs in a tiled map application, so there 
are a lot of small pixbufs being repeatedly read and then deallocated.

 ...Akkana


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-15 Thread Thomas Passin via Python-list

On 1/15/2024 6:27 PM, Greg Ewing via Python-list wrote:

On 16/01/24 11:55 am, Mats Wichmann wrote:
Windows natively has something called python.exe and python3.exe which 
is interfering here


I'm wondering whether py.exe should be taught to recognise these stubs
and ignore them. This sounds like something that could trip a lot of
people up.


There are registry entries that say where all the python.org install 
locations are.  I suppose, but don't know, that py.exe checks them.  The 
registry entries are inComputer\HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-15 Thread Thomas Passin via Python-list

On 1/15/2024 1:26 PM, Mats Wichmann via Python-list wrote:

On 1/15/24 09:44, Sibylle Koczian via Python-list wrote:


First and foremost I want to understand why I'm seeing this:

- Python scripts with "/usr/bin/env python3" as shebang line work as 
expected on a computer with Windows 10 and Python 3.11.5. They have 
worked for years on this machine, using either the latest Python or 
one version before (depending on availability of some packages). There 
is a virtual machine with ArchLinux on the same machine and some of 
the scripts are copies from that.


- I've got a second computer with Windows 11 and I installed Python 
3.12.1 on it. After copying some scripts from my first computer I 
found that I couldn't start them: not by entering the script name in a 
console, not using py.exe, not double clicking in the explorer. 
Entering \python  probably worked 
- I think I tried that too, but I'm not really sure, because that's 
really not practical.


In the Python documentation for versions 3.11 and 3.12 I found no 
differences regarding py.exe and shebang lines.


Then I removed the "/env" from the shebang lines and could start the 
scripts from the second computer. That certainly is a solution, but 
why???


It's because of Windows itself.  The default nowadays is that irritating 
little stub that prompts you to go install Python from the WIndows 
store.  When you use the "env" form, it looks for python (or python3 in 
your case) in the PATH *first* and you'll get a hit.   Mine looks like:


C:\Users\mats\AppData\Local\Microsoft\WindwsApps\python.exe and python3.exe

you can check what it's doing for you by using the "where" command in a 
windows shell.


On your older Windows 10 machine you either never had that stub - I 
don't know when it was added, maybe someone from Microsoft listening 
here knows - or it's been superseded by changes to the PATH, or 
something.  On my fairly new Win 11 box the base of that path is early 
in the user portion of PATH, so that must be a default.


py.exe without the "/usr/bin/env" magic doesn't put PATH searching 
first, according to that snip from the docs that's been posted here 
several times., so you shouldn't fall down that particular rathole.


Python from the App Store is not the same as Python from python.org:

"The Microsoft Store package is a simple installation of Python that is 
suitable for running scripts and packages, and using IDLE or other 
development environments. It requires Windows 10 and above, but can be 
safely installed without corrupting other programs. It also provides 
many convenient commands for launching Python and its tools."


- https://docs.python.org/3/using/windows.html

Also:

"The Windows Store distribution of Python is a sandboxed application ... 
The internal components of Windows Store apps are protected from being 
accessed from other applications, and so the PyXLL add-in cannot use the 
Python DLLs and packages that are installed as part of the Windows Store 
Python app."


From the PyXLL support site -

https://support.pyxll.com/hc/en-gb/articles/4417634326675-Python-installed-via-the-Windows-Store-cannot-be-used-with-PyXLL

The "py" launcher is installed by the installer from python.org.




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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-14 Thread Thomas Passin via Python-list

On 1/14/2024 8:54 AM, Thomas Passin via Python-list wrote:

On 1/14/2024 7:48 AM, Sibylle Koczian via Python-list wrote:

Am 09.01.2024 um 12:36 schrieb Barry Scott via Python-list:



On 7 Jan 2024, at 15:09, Sibylle Koczian via Python-list 
 wrote:


Oh, and the two Windows and Python versions are on two different 
computers.


Will remove the "/env" from my shebang lines, even if I don't 
understand what's happening.


Thanks for the details.

Only thing I can think of is that "python" may be defaulting to mean 
python 2.

If you use "#!/usr/bin/env python3" it may work on both.


No, it doesn't. That's the form I started with. When it didn't work I 
thought "python3" might be too old, because Python 2 is dead for so long.


Did you creates a py.ini file to configure py.exe?

See if you have %userappdata%\py.ini on either windows 10 or windows 11.
If so what is its contents?


No to both.


I've tried with and without a py.ini and cannot duplicate what you see.



It really seems strange. Only thing I can think of - and I don't 
really believe in that idea: as far as I know in Windows 11 the 
handling of PATH has changed. My Python isn't on the path, perhaps 
that is it. A shebang line without "/env" doesn't check the path, right?


 From what I've read recently, if you have a Python program that starts 
with a shebang line with any of four standard unix-like paths, then 
Python (not Windows) will look for a version of Python in standard 
locations - *NOT* in the shebang line locations:


I meant to write "the Python launcher", that is, the "py" program. 
Normal Python installs on Windows install the launcher and Windows will 
run it on ".py" files if no other program has been specified on the 
command line.


"To allow shebang lines in Python scripts to be portable between Unix 
and Windows, this launcher supports a number of ‘virtual’ commands to 
specify which interpreter to use. The supported virtual commands are:


/usr/bin/env
/usr/bin/python
/usr/local/bin/python
python
"

Also -
"The /usr/bin/env form of shebang line has one further special property. 
Before looking for installed Python interpreters, this form will search 
the executable PATH for a Python executable matching the name provided 
as the first argument. This corresponds to the behaviour of the Unix env 
program, which performs a PATH search. If an executable matching the 
first argument after the env command cannot be found, but the argument 
starts with python, it will be handled as described for the other 
virtual commands.

"

There are some other complications, too, depending on whether you 
specify bare "python" or some specific version. The form with 
"/usr/bin/env" is the closest to the unix behavior, in that it searches 
the PATH.  And you write that your intended version of Python is not on 
the path.


IOW, these shebang lines don't work the way you seem to think that they do.

See https://docs.python.org/3/using/windows.html for a more complete 
rundown.


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-14 Thread Thomas Passin via Python-list

On 1/14/2024 7:48 AM, Sibylle Koczian via Python-list wrote:

Am 09.01.2024 um 12:36 schrieb Barry Scott via Python-list:



On 7 Jan 2024, at 15:09, Sibylle Koczian via Python-list 
 wrote:


Oh, and the two Windows and Python versions are on two different 
computers.


Will remove the "/env" from my shebang lines, even if I don't 
understand what's happening.


Thanks for the details.

Only thing I can think of is that "python" may be defaulting to mean 
python 2.

If you use "#!/usr/bin/env python3" it may work on both.


No, it doesn't. That's the form I started with. When it didn't work I 
thought "python3" might be too old, because Python 2 is dead for so long.


Did you creates a py.ini file to configure py.exe?

See if you have %userappdata%\py.ini on either windows 10 or windows 11.
If so what is its contents?


No to both.


I've tried with and without a py.ini and cannot duplicate what you see.



It really seems strange. Only thing I can think of - and I don't really 
believe in that idea: as far as I know in Windows 11 the handling of 
PATH has changed. My Python isn't on the path, perhaps that is it. A 
shebang line without "/env" doesn't check the path, right?


From what I've read recently, if you have a Python program that starts 
with a shebang line with any of four standard unix-like paths, then 
Python (not Windows) will look for a version of Python in standard 
locations - *NOT* in the shebang line locations:


"To allow shebang lines in Python scripts to be portable between Unix 
and Windows, this launcher supports a number of ‘virtual’ commands to 
specify which interpreter to use. The supported virtual commands are:


/usr/bin/env
/usr/bin/python
/usr/local/bin/python
python
"

Also -
"The /usr/bin/env form of shebang line has one further special property. 
Before looking for installed Python interpreters, this form will search 
the executable PATH for a Python executable matching the name provided 
as the first argument. This corresponds to the behaviour of the Unix env 
program, which performs a PATH search. If an executable matching the 
first argument after the env command cannot be found, but the argument 
starts with python, it will be handled as described for the other 
virtual commands.

"

There are some other complications, too, depending on whether you 
specify bare "python" or some specific version. The form with 
"/usr/bin/env" is the closest to the unix behavior, in that it searches 
the PATH.  And you write that your intended version of Python is not on 
the path.


IOW, these shebang lines don't work the way you seem to think that they do.

See https://docs.python.org/3/using/windows.html for a more complete 
rundown.

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


Re: Extract lines from file, add to new files

2024-01-11 Thread Thomas Passin via Python-list

On 1/11/2024 1:27 PM, MRAB via Python-list wrote:

On 2024-01-11 18:08, Rich Shepard via Python-list wrote:

It's been several years since I've needed to write a python script so I'm
asking for advice to get me started with a brief script to separate names
and email addresses in one file into two separate files: 
salutation.txt and

emails.txt.

An example of the input file:

Calvin
cal...@example.com

Hobbs
ho...@some.com

Nancy
na...@herown.com

Sluggo
slu...@another.com

Having extracted salutations and addresses I'll write a bash script using
sed and mailx to associate a message file with each name and email 
address.


I'm unsure where to start given my lack of recent experience.


 From the look of it:

1. If the line is empty, ignore it.

2. If the line contains "@", it's an email address.

3. Otherwise, it's a name.


You could think about a single Python script that looks through your 
input file and constructs all the message files without ever writing 
separate salutation and address files at all.  Then you wouldn't need to 
write the sed and mailx scripts.  It shouldn't be much harder than 
peeling out the names and addresses into separate files.


If you haven't written any Python for some years, the preferred way to 
read and write files is using a "with" statement, like this:


with open('email_file.txt', encoding = 'utf-8') as f:
lines = f.readlines()
for line in lines:
if not line.strip():  # Skip blank lines
continue
# Do something with this line

You don't need to close the file because when the "with" block ends the 
file will be closed for you.


If the encoding is not utf-8 and you know what it will be, use that 
encoding instead.


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


Re: Using my routines as functions AND methods

2024-01-04 Thread Thomas Passin via Python-list

On 1/3/2024 8:00 PM, Alan Gauld via Python-list wrote:

On 03/01/2024 22:47, Guenther Sohler via Python-list wrote:

Hi,

In my cpython i have written quite some functions to modify "objects".
and their python syntax is e.g.\

translate(obj, vec). e.g whereas obj is ALWAYS first argument.



However, I also want to use these functions as class methods without having
to
write the function , twice. When using the SAME function as a methos, the
args tuple must insert/contain "self" in the first location, so i have
written a function to do that:


I'm probably missing something obvious here but can't you
just assign your function to a class member?

def myFunction(obj, ...): ...

class MyClass:
 myMethod = myFunction


Then you can call it as

myObject = MyClass()
myObject.myMethod()

A naive example seems to work but I haven't tried anything
complex so there is probably a catch. But sometimes the simple
things just work?


That works if you assign the function to a class instance, but not if 
you assign it to a class.


def f1(x):
print(x)
f1('The plain function')

class Class1:
pass

class Class2:
pass

c1 = Class1()
c1.newfunc = f1
c1.newfunc('f1 assigned to instance') # Works as intended

Class2.newfunc = f1
c2 = Class2()
c2.newfunc('f1 assigned to class')  # Complains about extra argument


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


Re: Using my routines as functions AND methods

2024-01-03 Thread Thomas Passin via Python-list

On 1/3/2024 11:17 PM, Thomas Passin wrote:

On 1/3/2024 8:00 PM, Alan Gauld via Python-list wrote:

On 03/01/2024 22:47, Guenther Sohler via Python-list wrote:

Hi,

In my cpython i have written quite some functions to modify "objects".
and their python syntax is e.g.\

translate(obj, vec). e.g whereas obj is ALWAYS first argument.


However, I also want to use these functions as class methods without 
having

to
write the function , twice. When using the SAME function as a methos, 
the

args tuple must insert/contain "self" in the first location, so i have
written a function to do that:


I'm probably missing something obvious here but can't you
just assign your function to a class member?

def myFunction(obj, ...): ...

class MyClass:
 myMethod = myFunction


Then you can call it as

myObject = MyClass()
myObject.myMethod()

A naive example seems to work but I haven't tried anything
complex so there is probably a catch. But sometimes the simple
things just work?


That works if you assign the function to a class instance, but not if 
you assign it to a class.


def f1(x):
     print(x)
f1('The plain function')

class Class1:
     pass

class Class2:
     pass

c1 = Class1()
c1.newfunc = f1
c1.newfunc('f1 assigned to instance') # Works as intended

Class2.newfunc = f1
c2 = Class2()
c2.newfunc('f1 assigned to class')  # Complains about extra argument


If your requirements are not very tricky, you can write a 
convert-to-method function yourself:


def f1(x):
print(x)
f1('The plain function')

class Class2:
pass

def convert_method(f):
"""Assign existing method without a "self" arg
   as a class's method.
"""
def fnew(instance, *args):
f(*args)
return fnew

Class2.newfunc = convert_method(f1)
c2 = Class2()
c2.newfunc('f1 assigned as method of Class2') # Prints the arg

This example does not make f1 aware of the self argument, but you asked 
to convert an existing function, and that function would not be aware of 
the self parameter. It's much like a decorator function, but is not here 
being used as a decorator. If you meant something else, please think out 
what you want and explain that.


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-02 Thread Thomas Passin via Python-list

On 1/2/2024 11:56 AM, Mats Wichmann via Python-list wrote:

On 1/1/24 12:53, Thomas Passin via Python-list wrote:

On Windows 10, a shebang line gets ignored in favor of Python 3.9.9 
(if invoked by the script name alone) or Python 3.12.1 (if invoked by 
the "py" launcher).


fwiw, you can also create an ini file to define to the launcher py which 
version should be the default, if no version is specified.


You might learn about this if you happen to read and remember the right 
part of the Python docs.  Otherwise you have no idea what py.exe is up 
to nor how it does it.  I would say that most people don't know there's 
an ini file, let alone what it can do.  Of course this situation isn't 
unique to py.exe!


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-01 Thread Thomas Passin via Python-list

On 1/1/2024 12:26 PM, Mats Wichmann via Python-list wrote:

On 1/1/24 07:11, Thomas Passin via Python-list wrote:

Here's how to find out what program Windows thinks it should use to 
run a ".py" file.  In a console:


C:\Users\tom>assoc .py
.py=Python.File

C:\Users\tom>ftype Python.file
Python.file="C:\Windows\py.exe" "%L" %*


That's not enough. There is now (has been for a while) a layered system, 
and this gives you just one layer, there may be other associations that 
win out.


Per somebody who actually knows:

 > The only way to determine the association without reimplmenting the 
shell's search is to simply ask the shell via AssocQueryString. Possibly 
PowerShell can provide this information. – Eryk Sun


"Possibly", eh?  In fact, on my system those layers must be in effect, 
since ftype claims that the "py" launcher will be used but in actual 
fact the old Python 3.9.9 is used instead, as I wrote earlier.  This is 
verified by this tiny Python script:


# Optional shebang line here
import sys
print(sys.executable)

Then run it with "py", a proposed shebang line, its plain name on the 
command line, whatever.  That will tell you for sure which Python 
executable gets launched by which technique.


On Windows 10, a shebang line gets ignored in favor of Python 3.9.9 (if 
invoked by the script name alone) or Python 3.12.1 (if invoked by the 
"py" launcher).


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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-01 Thread Thomas Passin via Python-list

On 1/1/2024 8:19 AM, Thomas Passin via Python-list wrote:

On 1/1/2024 6:02 AM, Sibylle Koczian via Python-list wrote:

Am 30.12.2023 um 04:04 schrieb Mike Dewhirst via Python-list:


I had assumed the OP had installed Python from the Microsoft shop and 
that's where py.exe must have come from.




In fact I didn't say in my post that I always get Python from 
python.org. When I started to use the language there was no Python 
from any Microsoft shop (I'm not sure there was a Microsoft shop, it 
was in the last millenium, Python 1.5 or 1.6). So I tend to forget 
that possible download source.


But in all this thread I didn't see a single explanation for my 
current situation: one and the same shebang line works on Windows 10 / 
Python 3.11 and doesn't work on Windows 11 / Python 3.12. I suspect 
Windows, because a change in the way Python 3.12 uses shebang lines 
should be visible in the documentation.


Happy new year to all!
Sibylle


Happy New Year!

I speculated that the shebang line didn't work on Windows 10 either, but 
you didn't realize it because the file associations were right to launch 
".py" programs with the right version of Python.  When the newer version 
of Python got installed, the default Python program to use, was not 
updated correctly, and the shebang line still has nothing to do with the 
launch failure.  This could happen if other the older install went into 
Program Files, while the newer one went into 
%USERPROFILE%\AppData\Local\Programs\Python.


This was backed up with all of 5 minutes of experimenting on my own 
computer, on which Windows launches ".py" programs with an old install 
of Python 3.9.9, but the py launcher launches Python 3.12 by default.


Since I am avoiding Windows 11, I can't try anything on it, so my 
thoughts above may not be relevant.


The Python docs for 3.12.1 cover shebang lines at

https://docs.python.org/3/using/windows.html

"If the first line of a script file starts with #!, it is known as a 
“shebang” line. Linux and other Unix like operating systems have native 
support for such lines and they are commonly used on such systems to 
indicate how a script should be executed. This launcher allows the same 
facilities to be used with Python scripts on Windows and the examples 
above demonstrate their use.


To allow shebang lines in Python scripts to be portable between Unix and 
Windows, this launcher supports a number of ‘virtual’ commands to 
specify which interpreter to use. The supported virtual commands are:


/usr/bin/env
/usr/bin/python
/usr/local/bin/python
python

For example, if the first line of your script starts with

#! /usr/bin/python
The default Python will be located and used. As many Python scripts 
written to work on Unix will already have this line, you should find 
these scripts can be used by the launcher without modification. If you 
are writing a new script on Windows which you hope will be useful on 
Unix, you should use one of the shebang lines starting with /usr."


But

"The /usr/bin/env form of shebang line has one further special property. 
Before looking for installed Python interpreters, this form will search 
the executable PATH for a Python executable matching the name provided 
as the first argument. This corresponds to the behaviour of the Unix env 
program, which performs a PATH search. If an executable matching the 
first argument after the env command cannot be found, but the argument 
starts with python, it will be handled as described for the other 
virtual commands. The environment variable PYLAUNCHER_NO_SEARCH_PATH may 
be set (to any value) to skip this search of PATH.


Shebang lines that do not match any of these patterns are looked up in 
the [commands] section of the launcher’s .INI file. This may be used to 
handle certain commands in a way that makes sense for your system. The 
name of the command must be a single argument (no spaces in the shebang 
executable), and the value substituted is the full path to the 
executable (additional arguments specified in the .INI will be quoted as 
part of the filename)."




Here's how to find out what program Windows thinks it should use to run 
a ".py" file.  In a console:


C:\Users\tom>assoc .py
.py=Python.File

C:\Users\tom>ftype Python.file
Python.file="C:\Windows\py.exe" "%L" %*

If your ".py" files are associated to the py.exe launcher, as mine are, 
then the launcher may try to use your shebang line and you need to make 
sure there aren't any spaces where there shouldn't be.


If your ".py" files are not associated with py.exe, the shebang line 
probably won't be used for anything.



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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-01 Thread Thomas Passin via Python-list

On 1/1/2024 6:02 AM, Sibylle Koczian via Python-list wrote:

Am 30.12.2023 um 04:04 schrieb Mike Dewhirst via Python-list:


I had assumed the OP had installed Python from the Microsoft shop and 
that's where py.exe must have come from.




In fact I didn't say in my post that I always get Python from 
python.org. When I started to use the language there was no Python from 
any Microsoft shop (I'm not sure there was a Microsoft shop, it was in 
the last millenium, Python 1.5 or 1.6). So I tend to forget that 
possible download source.


But in all this thread I didn't see a single explanation for my current 
situation: one and the same shebang line works on Windows 10 / Python 
3.11 and doesn't work on Windows 11 / Python 3.12. I suspect Windows, 
because a change in the way Python 3.12 uses shebang lines should be 
visible in the documentation.


Happy new year to all!
Sibylle


Happy New Year!

I speculated that the shebang line didn't work on Windows 10 either, but 
you didn't realize it because the file associations were right to launch 
".py" programs with the right version of Python.  When the newer version 
of Python got installed, the default Python program to use, was not 
updated correctly, and the shebang line still has nothing to do with the 
launch failure.  This could happen if other the older install went into 
Program Files, while the newer one went into 
%USERPROFILE%\AppData\Local\Programs\Python.


This was backed up with all of 5 minutes of experimenting on my own 
computer, on which Windows launches ".py" programs with an old install 
of Python 3.9.9, but the py launcher launches Python 3.12 by default.


Since I am avoiding Windows 11, I can't try anything on it, so my 
thoughts above may not be relevant.


The Python docs for 3.12.1 cover shebang lines at

https://docs.python.org/3/using/windows.html

"If the first line of a script file starts with #!, it is known as a 
“shebang” line. Linux and other Unix like operating systems have native 
support for such lines and they are commonly used on such systems to 
indicate how a script should be executed. This launcher allows the same 
facilities to be used with Python scripts on Windows and the examples 
above demonstrate their use.


To allow shebang lines in Python scripts to be portable between Unix and 
Windows, this launcher supports a number of ‘virtual’ commands to 
specify which interpreter to use. The supported virtual commands are:


/usr/bin/env
/usr/bin/python
/usr/local/bin/python
python

For example, if the first line of your script starts with

#! /usr/bin/python
The default Python will be located and used. As many Python scripts 
written to work on Unix will already have this line, you should find 
these scripts can be used by the launcher without modification. If you 
are writing a new script on Windows which you hope will be useful on 
Unix, you should use one of the shebang lines starting with /usr."


But

"The /usr/bin/env form of shebang line has one further special property. 
Before looking for installed Python interpreters, this form will search 
the executable PATH for a Python executable matching the name provided 
as the first argument. This corresponds to the behaviour of the Unix env 
program, which performs a PATH search. If an executable matching the 
first argument after the env command cannot be found, but the argument 
starts with python, it will be handled as described for the other 
virtual commands. The environment variable PYLAUNCHER_NO_SEARCH_PATH may 
be set (to any value) to skip this search of PATH.


Shebang lines that do not match any of these patterns are looked up in 
the [commands] section of the launcher’s .INI file. This may be used to 
handle certain commands in a way that makes sense for your system. The 
name of the command must be a single argument (no spaces in the shebang 
executable), and the value substituted is the full path to the 
executable (additional arguments specified in the .INI will be quoted as 
part of the filename)."



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


Re: mypy question

2023-12-30 Thread Thomas Passin via Python-list

On 12/30/2023 9:14 AM, Thomas Passin via Python-list wrote:

On 12/29/2023 10:02 AM, Karsten Hilbert via Python-list wrote:

I agree that mypy's grasp of my intent from

queries:list[dict[str, str | list | dict[str, Any]]]=None,

into

"List[Dict[str, Union[str, List[Any], Dict[str, Any"

seems accurate. I just don't understand why list[dict[str,
str]] should not pass that construct.


I made a tiny test program with your type signature, and got this error 
message from mypy:


c:\temp\python\typing_test.py:3: error: X | Y syntax for unions requires 
Python 3.10  [syntax]


Aside from that, this variation causes no mypy error (you must use 
Sequence instead of List), and is also more clear about what you are 
trying to get:


from typing import Union, Sequence, Dict

DictType1 = Dict[str, str]
DictType2 = Dict[str, Sequence]
DictType3 = Dict[str, Dict]
QueryType = Sequence[Union[DictType1, DictType2, DictType3]]

def test_typing(queries:QueryType=None):
     print(type(queries))

d1 = {'k1': 'v1', 'k2': 'v2'}
queries = [d1,]
test_typing(queries)

I'm not sure if this captures exactly what you want, but it avoids the 
problem where mypy does not regard str and Union[str, list] as 
equivalent types.  I tested this using Python 3.12.


In doing more testing, I have learned that my suggestion above does 
work, *except* that you cannot mix-and-match different DictTypex types 
within the same Sequence - meaning within the same query argument.  Any 
of the Union types is OK but they all have to be the same in any instance.


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


Re: mypy question

2023-12-30 Thread Thomas Passin via Python-list

On 12/29/2023 10:02 AM, Karsten Hilbert via Python-list wrote:

Am Fri, Dec 29, 2023 at 07:49:17AM -0700 schrieb Mats Wichmann via Python-list:


I am not sure why mypy thinks this

gmPG2.py:554: error: Argument "queries" to "run_rw_queries" has incompatible type 
"List[Dict[str, str]]"; expected
"List[Dict[str, Union[str, List[Any], Dict[str, Any"  [arg-type]
 rows, idx = run_rw_queries(link_obj = conn, queries = 
queries, return_data = True)
   
^~~

should be flagged. The intent is for "queries" to be

a list
of dicts
with keys of str
and values of
str OR
list of anything OR
dict with
keys of str
and values of anything

I'd have thunk list[dict[str,str]] matches that ?


Dict[str, str] means the key type and value type should both be strings,


Indeed, I know that much, list[dict[str, str]] is what is getting
passed in in this particular invocation of run_rw_queries().

For what it's worth here's the signature of that function:

def run_rw_queries (
link_obj:_TLnkObj=None,
queries:list[dict[str, str | list | dict[str, Any]]]=None,
end_tx:bool=False,
return_data:bool=None,
get_col_idx:bool=False,
verbose:bool=False
) -> tuple[list[dbapi.extras.DictRow], dict[str, int] | None]:

Given that I would have thought that passing in
list[dict[str, str]] for "queries" ought to be type safe.
Mypy indicates otherwise which I am not grokking as to why.


but in your
retelling above you indicate lots of possible value types... actually the mypy 
guess
seems to be a pretty good recreation of your psuedo-code description.


I agree that mypy's grasp of my intent from

queries:list[dict[str, str | list | dict[str, Any]]]=None,

into

"List[Dict[str, Union[str, List[Any], Dict[str, Any"

seems accurate. I just don't understand why list[dict[str,
str]] should not pass that construct.


Maybe better to ask the mypy people directly.


Karsten
--
GPG  40BE 5B0E C98E 1713 AFA6  5BC0 3BEA AC80 7D4F C89B


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


Re: Aw: Re: mypy question

2023-12-30 Thread Thomas Passin via Python-list

On 12/30/2023 10:08 AM, Karsten Hilbert via Python-list wrote:

Dear Thomas,

thanks for taking the time to look into my issue.

Maybe it helps if I explain what I want (sorry that my web mailer does not 
respect
indentation, I will insert dots).

I want a function to run SQL queries:

run_queries(conn, queries):
...for q in queries:
..conn.execute(q)

I now want to add type hints such that my large codebase can
be checked for silly doings. First, queries is to be a list
of the SQL to run:

run_queries(conn, queries:list):

Then, each list entry can be

...a string holding simple, complete SQL (say "SELECT 1")

run_queries(conn, queries:list[str]):


It occurs to me that you could simplify things if you converted those 
plain query strings to dicts:


'SELECT 1' --> {'SQL': 'SELECT 1'}

I'm fairly sure your database queries don't actually give you strings or 
dicts, right?  You probably get lists (or iterators) of tuples and 
somewhere you convert them to the arguments you are feeding to 
run_queries().  At least, that is how the standard Python db adapters 
work. If you change that conversion step, your arguments to 
run_queries() will all be lists of dicts, making your code simpler and 
reducing the complexity of the type hints.



or

...a dict holding the SQL and arguments for parameters

run_queries(conn, queries:list[dict]):

So, taken together:

run_queries(conn, queries:list[str|dict]):

(yes, this is in Python 3.11/3.12)

Now, when it is a list of dicts I want to further constrain the
dicts. Each is to contain the keys "SQL" and "args". So the keys
are of type str. The values for the keys will be of various types,
such that I chose Any as pseudo-type, so that each list entry that
is of type dict should be dict[str, Any], hence:

queries = [{'SQL': 'SELECT %(value)s', 'args': {'value': 1}}]

and

run_queries(conn, queries:list[str|dict[str, Any]]):

If I now call this function with a simple SQL query:

SQL_query = 'SELECT 1'  # should be type str ?
queries = [SQL_query]   # should be type list[str] ?
run_queries(conn, queries = queries)

and run mypy over that (at least inside my complex codebase) I will
get a type mismatch being hinted at.

So far I don't grasp at which point my reasoning above is faulty.

Karsten


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


Re: Aw: Re: mypy question

2023-12-30 Thread Thomas Passin via Python-list

On 12/30/2023 10:08 AM, Karsten Hilbert via Python-list wrote:

Dear Thomas,

thanks for taking the time to look into my issue.

Maybe it helps if I explain what I want (sorry that my web mailer does not 
respect
indentation, I will insert dots).

I want a function to run SQL queries:

run_queries(conn, queries):
...for q in queries:
..conn.execute(q)

I now want to add type hints such that my large codebase can
be checked for silly doings. First, queries is to be a list
of the SQL to run:

run_queries(conn, queries:list):

Then, each list entry can be

...a string holding simple, complete SQL (say "SELECT 1")

run_queries(conn, queries:list[str]):

or

...a dict holding the SQL and arguments for parameters

run_queries(conn, queries:list[dict]):

So, taken together:

run_queries(conn, queries:list[str|dict]):

(yes, this is in Python 3.11/3.12)

Now, when it is a list of dicts I want to further constrain the
dicts. Each is to contain the keys "SQL" and "args". So the keys
are of type str. The values for the keys will be of various types,
such that I chose Any as pseudo-type, so that each list entry that
is of type dict should be dict[str, Any], hence:

queries = [{'SQL': 'SELECT %(value)s', 'args': {'value': 1}}]

and

run_queries(conn, queries:list[str|dict[str, Any]]):

If I now call this function with a simple SQL query:

SQL_query = 'SELECT 1'  # should be type str ?
queries = [SQL_query]   # should be type list[str] ?
run_queries(conn, queries = queries)

and run mypy over that (at least inside my complex codebase) I will
get a type mismatch being hinted at.

So far I don't grasp at which point my reasoning above is faulty.

Karsten


I am not very expert in Python type hints.  In working up the example 
program I just posted, I got an error message from mypy that remarked 
that "list" is invariant, and to try Sequence which is "covariant".  I 
don't know what that means (and I haven't looked into it yet), but when 
I changed from list to Sequence as suggested, mypy stopped complaining.


Here is the exact error message, and it has a reference you might want 
to follow up with:


c:\temp\python\typing_test.py:16: note: "List" is invariant -- see 
https://mypy.readthedocs.io/en/stable/common_issues.html#variance
c:\temp\python\typing_test.py:16: note: Consider using "Sequence" 
instead, which is covariant


Before that, mypy insisted that str and Union[str, list] were 
incompatible argument types, which is something you are seeing, too.


I suggest that you build up your types as in my example, so that it's 
very clear what they are and very easy to change them, and use Sequence 
instead of List (or list).  See if that will do the job.


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


Re: mypy question

2023-12-30 Thread Thomas Passin via Python-list

On 12/29/2023 10:02 AM, Karsten Hilbert via Python-list wrote:

I agree that mypy's grasp of my intent from

queries:list[dict[str, str | list | dict[str, Any]]]=None,

into

"List[Dict[str, Union[str, List[Any], Dict[str, Any"

seems accurate. I just don't understand why list[dict[str,
str]] should not pass that construct.


I made a tiny test program with your type signature, and got this error 
message from mypy:


c:\temp\python\typing_test.py:3: error: X | Y syntax for unions requires 
Python 3.10  [syntax]


Aside from that, this variation causes no mypy error (you must use 
Sequence instead of List), and is also more clear about what you are 
trying to get:


from typing import Union, Sequence, Dict

DictType1 = Dict[str, str]
DictType2 = Dict[str, Sequence]
DictType3 = Dict[str, Dict]
QueryType = Sequence[Union[DictType1, DictType2, DictType3]]

def test_typing(queries:QueryType=None):
print(type(queries))

d1 = {'k1': 'v1', 'k2': 'v2'}
queries = [d1,]
test_typing(queries)

I'm not sure if this captures exactly what you want, but it avoids the 
problem where mypy does not regard str and Union[str, list] as 
equivalent types.  I tested this using Python 3.12.




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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2023-12-22 Thread Thomas Passin via Python-list

On 12/22/2023 7:27 PM, Michael Torrie via Python-list wrote:

On 12/22/23 07:02, Thomas Passin via Python-list wrote:

On my Windows 10 machine, Python scripts run without a shebang line.
Perhaps Windows 11 has added the ability to use one, but then you would
need to use the actual location of your Python executable.


Yes if you associate .py or .pyw with python.exe (or pythonw.exe), then
things work as you describe.  However it's no longer recommended to do
that.

Instead---and I think this is the default now when you install
python---you should associate both .py and .pyw files with the py
launcher (py.exe) and it will examine the shebang line of the script and
determine which version of python to run. As I said this should work
regardless of the path listed in the shebang.  Note that the shebang is
meaningless to Windows itself, and Windows Explorer. It is only
meaningful to the py launcher.  So it's customary to just use a
unix-style shebang in your python scripts.  So either #!/usr/bin/python3
or #!/usr/bin/env python3 as you would in unix.

Using the py launcher as your Windows association with .py and.pyw files
you can have multiple versions of python installed and everything works
as it should, according to your shebang, just like on Unix.


I actually don't remember how to set up the association for Python 
files.  I just always type the "py" launcher anyway, as in


py -m pip instal ...

I think that the association with py.exe must only happen if you install 
to Program Files.  As I said in my previous post, Windows still sticks 
with launching Python files with Python 3.9 even though I'm three 
version beyond that.  3.9 is the only one I installed to Program Files.


In my experience one should always make sure to know what version of 
Python is being used, at least if there is more than one version 
installed on the computer.  Even on Linux using a shebang line can be 
tricky, because you are likely to get the system's version of Python, 
and that often is not what you want.  OTOH you don't want to go 
symlinking python3 to some other version of python because then the OS 
system may not work right.  So either you have to specify the Python 
version in the shebang, or just specify the right version on the command 
line.  In that case you might as well not have included the shebang line 
at all.


I may be more sensitive to this issue because I run many different Linux 
distros in VMs to check a few programs I support to make sure they can 
run on Linux as well as Windows.  What Linux, you ask?  Well, who knows 
what our users will use? So I'm always getting Python version 
mix-and-match problems.  The system will still be at Python 3.10 but I 
need Python 3.11.  The system uses Python 3.11 but we shouldn't (or 
cannot) install our dependencies so we need a parallel install.  Etc, etc.


It's just better not to make assumptions about which version of Python 
will be running. Just specify it yourself when you can, and then you can 
be sure.

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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2023-12-22 Thread Thomas Passin via Python-list

On 12/22/2023 7:19 PM, Barry wrote:




On 23 Dec 2023, at 00:15, Thomas Passin via Python-list 
 wrote:

In neither case is the shebang line used.


As i understand it, not in front of my windows box to check.
The handler for .py file extension is set to be the py.exe
It is py.exe that understands shebang lines.


Not on my system. It may depend on whether Python gets installed to 
Program Files or to %USERPROFILE%/AppData/Local/Programs/Python.  Python 
3.9 is the last verson I installed to Program Files, and that's the 
version that Windows thinks it should use to run Python files.


Run the little test program I posted.  That will tell you which version 
of Python the system wants to use.

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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2023-12-22 Thread Thomas Passin via Python-list

On 12/22/2023 9:29 AM, Sibylle Koczian via Python-list wrote:

Am 22.12.2023 um 14:13 schrieb Barry:



On 22 Dec 2023, at 12:39, Sibylle Koczian via Python-list 
 wrote:


Hello,

I always install Python on Windows in the same manner:

- Python is not on the path,
- it is installed for all users,
- the Python Launcher is installed for all users,
- the file types .py, .pyw etc. are associated with Python.

My shebang line is usually "#!/usr/bin/env python3".

This has always worked well. I could run Python scripts in a console
window entering just the script name, by double clicking in the explorer
or using WIN+r; the two last variants for GUI or for scripts with
something like "input('Leave with Enter')" at the end.

Now I've got a new computer with Windows 11 and I've installed Python
3.12.1. On my older machine it's Windows 10 and Python 3.11.5. Reading
the Python documentation it seems my shebang lines should work as before
- but they don't. The error message:

"Unable to create process using 'C:\usr\bin\env\python
"C:\Eigen\Src\launcher_versuche.py" ': Das System kann die angegebene
Datei nicht finden."

Without the "env" in the shebang line and only without it everything
works as expected - but that's contrary to the documentation, isn't it?


This suggests a typo in the shebang line. Is there a space between env 
and python?


Barry



Tried several variants with the same script:

#!/usr/bin/env python3
# That's how I wrote it for Windows 10 / Python 3.11. It works there.

#!/usr/bin/env python
#!/usr/bin/env/python

The error messages vary a little. This is a German Windows installation,
the two variants with the space produce the same German error message,
the third produces the message I've put into my first description.

The working variant on Windows 11 / Python 3.12 is "#!/usr/bin python".


There is some important context that is missing here.  Python on Windows 
does not normally install to that location.  That is not even a Windows 
path, neither by directory name nor by path separators.


In addition, Powershell and cmd.exe do not use a shebang line, at least 
through Windows 10.  Instead, they use whatever executable has been 
registered for a file extension.  This may or may not be the version you 
think.  On my system, the OS will use Python 3.9, but actually the most 
recent Python version on my system is Python 3.12. I can demonstrate the 
difference:  here is a tiny Python file with a shebang line, called 
showme.py:


#! %USERPROFILE%\AppData\Local\Programs\Python\Python312\python.exe
import sys
print(sys.executable)

Run this with the "py" launcher:
py showme.py
# prints C:\Users\tom\AppData\Local\Programs\Python\Python312\python.exe

Run it by invoking just the script's name:
showme.py
# prints C:\Program Files\Python39\python.exe

In neither case is the shebang line used.

This makes me think that maybe the Linux subsystem for Windows is being 
used here. If so, possibly the syntax for a shebang line has been 
tightened up, or there's a typo.  Either way, I would not automatically 
assume that Windows (at least through Windows 10) ever used the shebang 
line for launching these scripts.




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


Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2023-12-22 Thread Thomas Passin via Python-list

On 12/22/2023 7:36 AM, Sibylle Koczian via Python-list wrote:

Hello,

I always install Python on Windows in the same manner:

- Python is not on the path,
- it is installed for all users,
- the Python Launcher is installed for all users,
- the file types .py, .pyw etc. are associated with Python.

My shebang line is usually "#!/usr/bin/env python3".

This has always worked well. I could run Python scripts in a console
window entering just the script name, by double clicking in the explorer
or using WIN+r; the two last variants for GUI or for scripts with
something like "input('Leave with Enter')" at the end.

Now I've got a new computer with Windows 11 and I've installed Python
3.12.1. On my older machine it's Windows 10 and Python 3.11.5. Reading
the Python documentation it seems my shebang lines should work as before
- but they don't. The error message:

"Unable to create process using 'C:\usr\bin\env\python
"C:\Eigen\Src\launcher_versuche.py" ': Das System kann die angegebene
Datei nicht finden."

Without the "env" in the shebang line and only without it everything
works as expected - but that's contrary to the documentation, isn't it?


How is a path for a linux location going to work on a Windows machine? 
On Windows, when you click on a script the OS tries to find the program 
that has been registered to run that script. Python would not have been 
installed to "C:\usr\bin\env\python".


On my Windows 10 machine, Python scripts run without a shebang line. 
Perhaps Windows 11 has added the ability to use one, but then you would 
need to use the actual location of your Python executable.


If you have several Python installations, it's better to run Python 
scripts using the "py" launcher, because Windows may have the wrong idea 
about which version to use.  The "where" command on my computer shows 
Python 3.9, but I'm actually using Python 12.


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


Re: Type hints - am I doing it right?

2023-12-13 Thread Thomas Passin via Python-list

On 12/13/2023 11:17 AM, Mats Wichmann via Python-list wrote:

On 12/13/23 00:19, Frank Millman via Python-list wrote:

I have to add 'import configparser' at the top of each of these 
modules in order to type hint the method.


This seems verbose. If it is the correct way of doing it I can live 
with it, but I wondered if there was an easier way.


Think of import as meaning "make this available in my current (module) 
namespace".


The actual import machinery only runs the first time, that is, if it's 
not already present in the sys.modules dict.


There's also the approach of importing the typing objects conditionally, 
as in this snippet from the Leo Editor 
(https://github.com/leo-editor/leo-editor)


if TYPE_CHECKING:  # pragma: no cover
from leo.core.leoCommands import Commands as Cmdr
from leo.core.leoGui import LeoKeyEvent as Event

Yes, it's more verbose but it makes clear what the intent is.
--
https://mail.python.org/mailman/listinfo/python-list


Re: IDLE editor suggestion.

2023-12-12 Thread Thomas Passin via Python-list

On 2023-12-12 08:22, Steve GS via Python-list wrote:
> Maybe this already exists but
> I have never seen it in any
> editor that I have used.
>
> It would be nice to have a
> pull-down text box that lists
> all of the searches I have
> used during this session. It
> would make editing a lot
> easier if I could select the
> previous searches rather than
> having to enter it every time.
>
> If this is inappropriate to
> post this here, please tell me
> where to go.
> Life should be so
> complicated.
>
EditPad has this.

So do Notepad++, EditPlus (not free but low cost, Windows only, and very 
good), and I'm sure many others that are much simpler than Visual Studio 
Code, for example.

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


  1   2   >