RE: A technique from a chatbot

2024-04-02 Thread AVI GROSS via Python-list
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





-Original Message-
From: Python-list  On 
Behalf Of Thomas Passin via Python-list
Sent: Tuesday, April 2, 2024 3:31 PM
To: python-list@python.org
Subject: Re: A technique from a chatbot

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 

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: A technique from a chatbot

2024-04-02 Thread Piergiorgio Sartor via Python-list

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


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,

--

piergiorgio

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


Re: Making 'compiled' modules work with multiple python versions on Linux

2024-04-02 Thread Barry via Python-list


> On 1 Apr 2024, at 18:14, Left Right via Python-list  
> wrote:
> 
> It sounds weird that symbols from Limited API are _missing_ (I'd
> expect them to be there no matter what library version you link with).

You have to specify the version of the limited API that you want to use.
Each release adds more symbols to the limited API.
So if you compile against 3.10 version it works with 3.10, 3.11, 3.12 etc,
but not with 3.9.

My pycxx project has test code that I use to verify pycxx’s use of python API.
You could check out the source and run my tests to see how things work.
It is on https://sourceforge.net/projects/cxx/

Barry


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


Re: Trying to use pyinstaller under python 3.11, and, recently started receiving error message about specific module/distribution

2024-04-02 Thread Barry via Python-list


> On 1 Apr 2024, at 15:52, Jacob Kruger via Python-list 
>  wrote:
> 
> Found many, many mentions of errors, with some of the same keywords, but, no 
> resolutions that match my exact issue at all.

Try asking the pyinstaller developers. I think there is a mailing list.

Barry
> 
> 
> As in, most of them are mentioning older versions of python, and, mainly 
> different platforms - mac and linux, but, various google searches have not 
> mentioned much of using it on windows, and having it just stop working.
> 
> 
> Now did even try shifting over to python 3.12, but, still no-go.
> 
> 
> If launch pyinstaller under python 3.10 on this exact same machine, 
> pyinstaller runs - just keep that older version hovering around for a couple 
> of occasional tests, partly since some of my target environments are still 
> running older versions of python, but anyway.
> 
> 
> Also, not really relevant, but, cx_freeze is perfectly able to generate 
> executables for this same code, but, then not combining all output into a 
> single file - will stick to that for now, but, not always as convenient, and, 
> still wondering what changed here.
> 
> 
> Jacob Kruger
> +2782 413 4791
> "Resistance is futile!...Acceptance is versatile..."
> 
> 
>> On 2024/03/31 14:51, Barry wrote:
>> 
 On 31 Mar 2024, at 13:24, Jacob Kruger via Python-list 
  wrote:
>>> 
>>> pkg_resources.DistributionNotFound: The 'altgraph' distribution was not 
>>> found and is required by the application
>> I think I have seen this error being discussed before…
>> 
>> A web search for pyinstaller and that error leads to people discussing why 
>> it happens it looks like.
>> 
>> Barry
>> 
>> 
> --
> https://mail.python.org/mailman/listinfo/python-list

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