Re: Is there a Python module to parse a date like the 'date' command in Linux?

2023-05-23 Thread Chris Green
Mike Dewhirst  wrote:
> [-- multipart/mixed, encoding 7bit, 22 lines --]
> 
> [-- text/plain, encoding base64, charset: UTF-8, 16 lines --]
> 
> On 21/05/2023 5:53 am, Chris Green wrote:
> > I'm converting a bash script to python as it has become rather clumsy
> > in bash.
> 
> What is the use case?
> 
A script I use to create diary entries, so it's very handy to be able
to give the date as 'yesterday' or 'friday'.

-- 
Chris Green
·
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a Python module to parse a date like the 'date' command in Linux?

2023-05-23 Thread Alex Pinkney
On Tue, 23 May 2023, 17:25 Chris Green,  wrote:

> Mike Dewhirst  wrote:
> > [-- multipart/mixed, encoding 7bit, 22 lines --]
> >
> > [-- text/plain, encoding base64, charset: UTF-8, 16 lines --]
> >
> > On 21/05/2023 5:53 am, Chris Green wrote:
> > > I'm converting a bash script to python as it has become rather clumsy
> > > in bash.
> >
> > What is the use case?
> >
> A script I use to create diary entries, so it's very handy to be able
> to give the date as 'yesterday' or 'friday'.
>
> --
> Chris Green
> ·
> --
> https://mail.python.org/mailman/listinfo/python-list



Hi, you may find dateparser useful:
https://dateparser.readthedocs.io/en/latest/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



On 20/05/2023 18:54, Alex Jando wrote:

I have many times had situations where I had a variable of a certain type, all 
I cared about it was one of it's methods.

For example:


import hashlib
hash = hashlib.sha256(b'word')
hash = hash.hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num = num.value


Now to be fair, in the two situations above, I could just access the method 
right as I declare the object, however, sometimes when passing values into 
functions, it's a lot messier to do that.

So what I'm suggesting is something like this:


import hashlib
hash = hashlib.sha256(b'word')
hash.=hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num.=value


It seems to me that this would encourage bad style.  When you write
    num = num.value
you are using num with two different meanings (an object and an 
attribute of it).  The original object is lost.
If down the line you needed to access another attribute of the object, 
you would have to backtrack:

    val = num.value
    spam = num.spam
or at least write the statements in the right order, so that you only 
overwrite num at the end:

    spam = num.spam
    num = num.value
Either way, you are making the code more fragile i.e. harder to maintain.
Now of course, in your use case it may be perfectly appropriate to write 
"num = num.value" as you did.

But IMO it's not something that should be encouraged in general.
Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Peter J. Holzer
On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote:
> On 20/05/2023 18:54, Alex Jando wrote:
> > So what I'm suggesting is something like this:
> > 
> > 
> > hash = hashlib.sha256(b'word')
> > hash.=hexdigest()
> > 
> > num = Number.One
> > num.=value
> > 
> It seems to me that this would encourage bad style.  When you write
>     num = num.value
> you are using num with two different meanings (an object and an
> attribute of it).

I think that's ok if it's the same thing at a high level.

I sometimes have a chain of transformations (e.g. first decode it, then
strip extra spaces, then normalize spelling, then look it up in a
database and replace it with the record, ...). Technically, of course
all these intermediate objects are different, and I could make that
explicit by using different variable names:

user_param = request.GET["user"]
user_decoded = str(user_param, encoding="utf-8")
user_stripped = user_decoded.strip()
user_normalized = user_stripped.lower()
user_object = orm.user.get(name=user_normalized)

But I find it easier to read if I just reuse the same variable name:

user = request.GET["user"]
user = str(user, encoding="utf-8")
user = user.strip()
user = user.lower()
user = orm.user.get(name=user)

Each instance only has a livetime of a single line (or maybe two or
three lines if I have to combine variables), so there's little risk of
confusion, and reusing the variable name makes it very clear that all
those intermediate results are gone and won't be used again.

hp


-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | [email protected] |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> But I find it easier to read if I just reuse the same variable name:
>
> user = request.GET["user"]
> user = str(user, encoding="utf-8")
> user = user.strip()
> user = user.lower()
> user = orm.user.get(name=user)
>
> Each instance only has a livetime of a single line (or maybe two or
> three lines if I have to combine variables), so there's little risk of
> confusion, and reusing the variable name makes it very clear that all
> those intermediate results are gone and won't be used again.
>

Small side point: You can make use of the bytes object's decode()
method to make the chaining much more useful here, rather than the
str() constructor.

This sort of code might be better as a single expression. For example:

user = (
request.GET["user"]
.decode("utf-8")
.strip()
.lower()
)
user = orm.user.get(name=user)

The pipeline is still visible, you've avoided the "user = user ."
replication, and you've ALSO avoided duplicating "user = " on each
line too.

IMO the ".=" syntax would actually be a bit of a nuisance in this
style of code. Consider how it would look, with your original str
constructor in the middle:

user = request.GET["user"]
user = str(user, encoding="utf-8")
user .= strip()
user .= lower()
user = orm.user.get(name=user)

The fact that two of them are ".=" rather than "=" is a bit too subtle
for my liking, possibly because the dot is so small.

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:22, Rob Cliffe  wrote:
>
>
> > This sort of code might be better as a single expression. For example:
> >
> > user = (
> >  request.GET["user"]
> >  .decode("utf-8")
> >  .strip()
> >  .lower()
> > )
> > user = orm.user.get(name=user)
> >
> >
> LOL.  And I thought I was the one with a (self-confessed) tendency to
> write too slick, dense, smart-alec code. 😁
> Indeed, I was itching to shorten it (starting with the low-hanging
> fruit: user = user.strip().lower() ).
> Seriously though: this kind of condensation can come unstuck when any of
> the steps need to be made more complicated.
> (Suppose request.GET might return ASCII, might return Unicode, depending
> on which server it was talking to.)

Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with
ASCII (it's a superset). You should always consistently get the same
data type (bytes or text) based on the library you're using.

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


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



This sort of code might be better as a single expression. For example:

user = (
 request.GET["user"]
 .decode("utf-8")
 .strip()
 .lower()
)
user = orm.user.get(name=user)


LOL.  And I thought I was the one with a (self-confessed) tendency to 
write too slick, dense, smart-alec code. 😁
Indeed, I was itching to shorten it (starting with the low-hanging 
fruit: user = user.strip().lower() ).
Seriously though: this kind of condensation can come unstuck when any of 
the steps need to be made more complicated.
(Suppose request.GET might return ASCII, might return Unicode, depending 
on which server it was talking to.)
Peter's actual code feels more Pythonic to me.  (It's even 2 lines 
shorter! 😎)

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


Re: Addition of a .= operator

2023-05-23 Thread Peter J. Holzer
On 2023-05-24 07:12:32 +1000, Chris Angelico wrote:
> On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> > But I find it easier to read if I just reuse the same variable name:
> >
> > user = request.GET["user"]
> > user = str(user, encoding="utf-8")
> > user = user.strip()
> > user = user.lower()
> > user = orm.user.get(name=user)
> >
> > Each instance only has a livetime of a single line (or maybe two or
> > three lines if I have to combine variables), so there's little risk of
> > confusion, and reusing the variable name makes it very clear that all
> > those intermediate results are gone and won't be used again.
> >
> 
> Small side point: You can make use of the bytes object's decode()
> method to make the chaining much more useful here, rather than the
> str() constructor.
> 
> This sort of code might be better as a single expression. For example:
> 
> user = (
> request.GET["user"]
> .decode("utf-8")
> .strip()
> .lower()
> )
> user = orm.user.get(name=user)

Yes, that probably wasn't the best example. I sort of deliberately
avoided method chaining here to make my point that you don't have to
invent a new variable name for every intermediate result, but of course
that backfired because in this case you don't need a variable name at
all. I should have used regular function calls ...

hp


-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | [email protected] |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:48, Peter J. Holzer  wrote:
>
> On 2023-05-24 07:12:32 +1000, Chris Angelico wrote:
> > On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> > > But I find it easier to read if I just reuse the same variable name:
> > >
> > > user = request.GET["user"]
> > > user = str(user, encoding="utf-8")
> > > user = user.strip()
> > > user = user.lower()
> > > user = orm.user.get(name=user)
> > >
> > > Each instance only has a livetime of a single line (or maybe two or
> > > three lines if I have to combine variables), so there's little risk of
> > > confusion, and reusing the variable name makes it very clear that all
> > > those intermediate results are gone and won't be used again.
> > >
> >
> > Small side point: You can make use of the bytes object's decode()
> > method to make the chaining much more useful here, rather than the
> > str() constructor.
> >
> > This sort of code might be better as a single expression. For example:
> >
> > user = (
> > request.GET["user"]
> > .decode("utf-8")
> > .strip()
> > .lower()
> > )
> > user = orm.user.get(name=user)
>
> Yes, that probably wasn't the best example. I sort of deliberately
> avoided method chaining here to make my point that you don't have to
> invent a new variable name for every intermediate result, but of course
> that backfired because in this case you don't need a variable name at
> all. I should have used regular function calls ...
>

In the context of a .= operator, though, that is *in itself* an
interesting data point: in order to find an example wherein the .=
operator would be plausible, you had to make the .= operator
unnecessary.

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:57, Rob Cliffe  wrote:
> > Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with
> > ASCII (it's a superset). You should always consistently get the same
> > data type (bytes or text) based on the library you're using.
> >
> > ChrisA
> OK, bad example.  The point remains: condensing each step to a single
> chained function can come unstuck when one of the steps needs to be made
> more complicated for some reason.

That's fair. Still, I wouldn't over-complicate a piece of code "just
in case" it needs to become more complicated in the future. I'd rather
code to what's needed now, and if that's a simple "decode as UTF-8",
that's great; maybe in the future I need to cope with an insane system
like "decode line by line, attempting UTF-8 first and falling back on
Windows-1252, then rejoin the lines", and that's the time to implement
that.

(Yes, I have had to do that. Although I think I cheated and used
ISO-8859-1 instead. It was a lot easier and I didn't really care about
precise handling, so long as MOST things were readable.)

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


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



On 23/05/2023 22:03, Peter J. Holzer wrote:

On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote:

On 20/05/2023 18:54, Alex Jando wrote:

So what I'm suggesting is something like this:


hash = hashlib.sha256(b'word')
hash.=hexdigest()

num = Number.One
num.=value


It seems to me that this would encourage bad style.  When you write
     num = num.value
you are using num with two different meanings (an object and an
attribute of it).

I think that's ok if it's the same thing at a high level.

I sometimes have a chain of transformations (e.g. first decode it, then
strip extra spaces, then normalize spelling, then look it up in a
database and replace it with the record, ...). Technically, of course
all these intermediate objects are different, and I could make that
explicit by using different variable names:

 user_param = request.GET["user"]
 user_decoded = str(user_param, encoding="utf-8")
 user_stripped = user_decoded.strip()
 user_normalized = user_stripped.lower()
 user_object = orm.user.get(name=user_normalized)

But I find it easier to read if I just reuse the same variable name:

 user = request.GET["user"]
 user = str(user, encoding="utf-8")
 user = user.strip()
 user = user.lower()
 user = orm.user.get(name=user)

Each instance only has a livetime of a single line (or maybe two or
three lines if I have to combine variables), so there's little risk of
confusion, and reusing the variable name makes it very clear that all
those intermediate results are gone and won't be used again.

 hp



Quite so.  I did imply in my full answer that this kind of thing can be 
appropriate in the right context.  I'm sure I've done it myself.
Your code is a beautiful example of when such "level-crossing" IS 
appropriate; creating a plethora of variables with a short useful life
would be a distraction which HINDERS readability ("Are any of these 
variables used later on?").
(Not to mention the effort of thinking up suitable variable names, and 
the effort of someone reading the code to assimilate them.)

But IMO your code would not really benefit from writing
        user .= strip()
        user .= lower()
and allowing it would have the disadvantage (apart from all the known 
costs of adding a new feature to Python) of encouraging bad style in the 
cases where it IS bad style.

Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


OT: Addition of a .= operator

2023-05-23 Thread dn via Python-list

On 24/05/2023 10.21, Rob Cliffe via Python-list wrote:



This sort of code might be better as a single expression. For example:

user = (
 request.GET["user"]
 .decode("utf-8")
 .strip()
 .lower()
)
user = orm.user.get(name=user)


LOL.  And I thought I was the one with a (self-confessed) tendency to 
write too slick, dense, smart-alec code. 😁
Indeed, I was itching to shorten it (starting with the low-hanging 
fruit: user = user.strip().lower() ).
Seriously though: this kind of condensation can come unstuck when any of 
the steps need to be made more complicated.

...

Peter's actual code feels more Pythonic to me.  (It's even 2 lines 
shorter! 😎)


On 24/05/2023 09.03, Peter J. Holzer wrote:
> I sometimes have a chain of transformations (e.g. first decode it, then
> strip extra spaces, then normalize spelling, then look it up in a
> database and replace it with the record, ...). Technically, of course
> all these intermediate objects are different, and I could make that
> explicit by using different variable names:
>
>  user_param = request.GET["user"]
>  user_decoded = str(user_param, encoding="utf-8")
>  user_stripped = user_decoded.strip()
>  user_normalized = user_stripped.lower()
>  user_object = orm.user.get(name=user_normalized)
>
> But I find it easier to read if I just reuse the same variable name:
>
>  user = request.GET["user"]
>  user = str(user, encoding="utf-8")
>  user = user.strip()
>  user = user.lower()
>  user = orm.user.get(name=user)
>
> Each instance only has a livetime of a single line (or maybe two or
> three lines if I have to combine variables), so there's little risk of
> confusion, and reusing the variable name makes it very clear that all
> those intermediate results are gone and won't be used again.


Once again/recently/another trainee came with a question about input() 
because he expected an number (cf input() providing a string). In this 
case, and to drive-home the point, preferred training illustration is:


quantity_input = input( "How many would you like? " )
quantity = float( quantity_input )

Many others, and I dare so all those who suffer from the aforementioned 
"itch", want to condense this into a single line.


However, (continuing @Peter's theme) such confuses things when something 
goes wrong - was the error in the input() or in the float()?

- particularly for 'beginners'
- and yes, we can expand the above discussion to talk about 
error-handling, and repetition until satisfactory data is input by the 
user or (?frustration leads to) EOD...


Accordingly, I'd start by favoring @Peter's "explicit" approach. However 
(as mentioned), we end-up with a bunch of names (storage-space) which 
are essentially unused - and many lint-er types will deplore such 
single-use [like it's s-u plastic].


Thus, advice becomes somewhat the opposite(!) of function parameter 
handling - there, I'm happy with one or two positional-parameters, but 
by three-or-more, this over-taxed brain starts begging/itching for 
named-parameters instead.


Now, the "easier" approach appeals. Indeed, if something goes wrong (per 
input()/float(), above), at least one has the assistance of a 
line-number (where error was noted). Further, using the PyCharm 
Debugger/pdb makes locating the design-error/coder's mistaken 
assumption, a snap.


A debatable-point is how much we should consider more junior-level 
programmers. IMHO more common functions such as strip() and lower() can 
be combined without much loss of readability or comprehension (apart 
from 'function-chaining' adding complication). Whereas, the other three 
lines are more likely to challenge - and/or become a source of concern 
if mods are requested...


However, some disagreement - which comes back to why the "_input" suffix 
(above) acts as an aide-memoire: When "user" is first used (hah!), it is 
the result of an http request. It is then transmogrified, until at the 
end where it is a query-result/object. Yes, however contrived and 
deliberately drawn-out the example, there is still a difference between 
the value which the code first produces (request/input) and that which 
eventually settles-out (orm/float).


Accordingly (perhaps), "user_request" or "user_requested" and "user" or 
"user_record" (according to the way 'that' ORM operates). Perhaps more 
psychology rather than coding?


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


Re: OT: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 10:12, dn via Python-list  wrote:
> However, (continuing @Peter's theme) such confuses things when something
> goes wrong - was the error in the input() or in the float()?
> - particularly for 'beginners'
> - and yes, we can expand the above discussion to talk about
> error-handling, and repetition until satisfactory data is input by the
> user or (?frustration leads to) EOD...

A fair consideration! Fortunately, Python has you covered.

$ cat asin.py
import math

print(
math.asin(
float(
input("Enter a small number: ")
)
)
)
$ python3 asin.py
Enter a small number: 1
1.5707963267948966
$ python3 asin.py
Enter a small number: 4
Traceback (most recent call last):
  File "/home/rosuav/tmp/asin.py", line 4, in 
math.asin(
ValueError: math domain error
$ python3 asin.py
Enter a small number: spam
Traceback (most recent call last):
  File "/home/rosuav/tmp/asin.py", line 5, in 
float(
ValueError: could not convert string to float: 'spam'

Note that the line numbers correctly show the true cause of the
problem, despite both of them being ValueErrors. So if you have to
debug this sort of thing, make sure the key parts are on separate
lines (even if they're all one expression, as in this example), and
then the tracebacks should tell you what you need to know.

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


where is requests

2023-05-23 Thread Rich Osborne
I have install Python 3.11.3 but my import requests does not work. I found 
documentation that refers to C:\python35 but I am on 3.11.3. Where do I find 
requests?



Sent from Mail for Windows

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


Re: where is requests

2023-05-23 Thread MRAB

On 2023-05-24 01:14, Rich Osborne wrote:

I have install Python 3.11.3 but my import requests does not work. I found 
documentation that refers to C:\python35 but I am on 3.11.3. Where do I find 
requests?

It's not part of the standard library. You can import it using pip. If 
you're on Windows, the recommended method is o use the Python Launcher 
and the pip module from a Command Prompt window:


py -m pip install requests

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


Tkinter docs?

2023-05-23 Thread Rob Cliffe via Python-list
I have recently started converting a large project to tkinter, starting 
with zero knowledge of tkinter.  (You are free to think: BAD IDEA. 😁)
I am well aware that adopting a new tool always involves a learning 
curve, and that one is prone to think that things are more difficult 
than they are/should be, and to belly-ache about it, and that in a year 
from now I'll probably wonder what I'm fussing about.

Nonetheless ISTM that there is a particular problem with tkinter:

    There doesn't seem to be any decent documentation for it anywhere.

 I seem to have spent al least 95% (feels more like 99%) of my time in 
research, only the rest available for coding.  Everything I've learned 
has come from scouring the Internet for Stack Overflow pages, videos, 
and other articles.  And while I'm VERY grateful for these resources, 
most of them cover very basic use, and if I want information on some 
more obscure technical point, I can only go on looking and looking and 
hope I eventually stumble upon what I'm looking for, or some acceptable 
substitute.
FWIW: The tkinter error messages are sometimes helpful, sometimes not, 
occasionally very helpful (as when I pass an invalid option parameter to 
a function and it tells me what the valid ones are).  I feel there is 
plenty of room for improvement.


One example for those familiar with tkinter (I assure you there are 
others) of how I struggle without adequate documentation:
    I had learned very early on that tkinter provides two versions of 
some classes: the original, or "tk" versions, and a later generation, 
the "ttk" versions (and I have to say that that was a turn-off, as it 
seemed that the learning curve has just got steeper).  It was surely not 
appropriate for me to delve deeply into this issue at that stage, as 
there were so many other things I didn't know (like, practically 
everything).  I decide to go with the "tk" versions pro tem, and to 
investigate the "ttk" versions later if it seemed like a good idea.  One 
annoyance is that some webpages are relevant to one version, some to the 
other, almost always without being explicit about which.  (Can't blame 
the "tk" ones, as they were probably written before "ttk" was invented.)
    I was writing a subclass of the Checkbutton class (tkinter's name 
for what I call a checkbox).  I needed to be able to (1) set (2) clear 
(3) interrogate the checked state.  This is easy to do if you associate 
a "variable" with each Checkbutton instance, as seems to be usual 
tkinter practice.  ("variable" is not a variable in the usual sense, but 
an object provided by tkinter that is linked to a GUI object (such as a 
Checkbutton), so that when the GUI object changes, the value of the 
"variable" changes, and vice versa.) However, I decided that I wanted to 
dispense with the variable, if possible.  (My motivation?  Simpler 
code.  Shorter code.  Avoiding using up resources by creating 
unnecessary objects.  You are free to think that I was misguided.  You 
are free to think that I should have been happy with something that 
worked.)  I didn't care whether I used a tk.Checkbutton or a 
ttk.Checkbutton.
    From various Internet articles I discovered (slowly, after wading 
through many articles that DID use a "variable"):
        A way of GETting the state of a tk.CheckButton (but not a 
ttk.CheckButton)
        A way of SETting the state of a ttk.CheckButton (but not a 
tk.CheckButton)
        Or the other way round.  Or something else.  I can no longer 
remember, and I didn't keep a record of all my trials and tribulations, 
and I can no longer trace which articles I read when.

    EVENTUALLY I discovered:
        For a ttk.CheckButton (only), where cb is the checkbox
            cb.state() returns a tuple of strings which contains, or 
doesn't, "selected", according to the checked state

            cb.state(["selected"]) sets the checked state
            cb.state(["!selected"]) clears the checked state
"Aha!" I thought.  "Problem solved".  Gleefully I wrote my code and 
tested it.
Er, well, not quite.  When the Checkbutton object was instantiated, it 
showed neither a checked nor an unchecked box, but a solid black box.  
This was the third or so-called "alternate" state provided by tkinter.  
(Gee, thanks.  Oh sorry, it's probably not your fault; as I understand 
it, tkinter, you're really just a wrapper.)

Further research revealed that I could get past this by writing
    cb.state(["!alternate", "!selected"])
when the object was instantiated.
Phew!  Finally got my code working.
But the story is not quite over.  To get the checked state I was using
    "selected" in cb.state()
While this works, later (in fact while composing this e-mail) I stumbled 
across

    cb.instate(["selected"])
which does the same thing but is, I guess, the preferred method.  I have 
amended my code accordingly.

(I don't know why the square brackets are necessary, but
    cb.instate("selected")
doesn't work.)
Sigh.  I suppose I have t

Re: Tkinter docs?

2023-05-23 Thread Grant Edwards
On 2023-05-24, Rob Cliffe via Python-list  wrote:
> I have recently started converting a large project to tkinter, starting 
> with zero knowledge of tkinter.  (You are free to think: BAD IDEA. 😁)

Well, you could be translating them to Tcl/Tk -- so on the scale of
bad ideas, your's barely registers.

> I am well aware that adopting a new tool always involves a learning 
> curve, and that one is prone to think that things are more difficult 
> than they are/should be, and to belly-ache about it, and that in a year 
> from now I'll probably wonder what I'm fussing about.
> Nonetheless ISTM that there is a particular problem with tkinter:
>
>   There doesn't seem to be any decent documentation for it anywhere.

Back in the day, the Grayson book was the definitive reference:

   https://www.amazon.com/Python-Tkinter-Programming-John-Grayson/dp/1884777813/

It's 20+ years old now, so the version of Python it uses is pretty
ancient, and I presume Tk has also changed a bit over the years, so...

There are a couple recent books, but I haven't looked at them:

   
https://www.amazon.com/Modern-Tkinter-Busy-Python-Developers-dp-1999149564/dp/1999149564/

   
https://www.amazon.com/Python-GUI-Programming-Tkinter-user-friendly/dp/1801815925/

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


RE: where is requests

2023-05-23 Thread Mike Dewhirst
Try pip install requests--(Unsigned mail from my phone)
 Original message From: Rich Osborne  
Date: 24/5/23  11:49  (GMT+10:00) To: [email protected] Subject: where is 
requests I have install Python 3.11.3 but my import requests does not work. I 
found documentation that refers to C:\python35 but I am on 3.11.3. Where do I 
find requests?Sent from Mail 
for Windows-- https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Tkinter docs?

2023-05-23 Thread aapost

On 5/23/23 21:18, Rob Cliffe wrote:


Comments, anyone?
Better yet (holds breath ...) can anyone point me towards some decent 
tkinter documentation?


The variables are slightly more integrated when using tcl/tk directly, 
python has to have the object so you can track/use them easier. And the 
variables are more of what is intended to track a widgets purpose, vs 
state stuff that is more the state of the displaying of the widget.


occasionally giving tcl/tk a try directly helps, and using the official 
tcl/tk docs in addition to a couple other decent docs below.


https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html
https://tkdocs.com/tutorial/styles.html

https://www.tcl.tk/man/tcl8.6/
https://www.tcl.tk/man/tcl8.6/TkCmd/contents.html
https://www.tcl.tk/man/tcl8.6/TkLib/contents.html

(this used to be some documentation that I only discovered existed 
recently, but most of it doesn't load and I don't know that anyone 
backed it up for rehosting..)

https://web.archive.org/web/20200227170827/http://effbot.org/tkinterbook

tk is decent for what it can do, (and it could do potentially more if 
you had a lifetime to dedicate to it, lol) and it's reasonably stable 
and not being perpetually hacked about and broken like gtk.


A couple additional pointers in case these haven't been figured out yet:
Running it interactively and using tab complete helps.
If you are running an app you can comment out the mytk.mainloop() 
statement then run python -i yourtk.py to give you access to all widgets 
live.
For navigating them, just come up with a widget naming convention that 
works for you in a similar vein to how tk does (like .frame.frame.label 
to start),

i.e.
main = tk.Tk()
main.frame = tk.Frame()
That way if you have anchored your widgets to something at the root 
level you can navigate down to whatever you are looking for easily. (you 
can also use winfo_children() iteratively to travel the way tcl 
structures them, but that is tedious).

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


Re: OT: Addition of a .= operator

2023-05-23 Thread dn via Python-list

On 24/05/2023 12.27, Chris Angelico wrote:

On Wed, 24 May 2023 at 10:12, dn via Python-list  wrote:

However, (continuing @Peter's theme) such confuses things when something
goes wrong - was the error in the input() or in the float()?
- particularly for 'beginners'
- and yes, we can expand the above discussion to talk about
error-handling, and repetition until satisfactory data is input by the
user or (?frustration leads to) EOD...


A fair consideration! Fortunately, Python has you covered.

$ cat asin.py
import math

print(
 math.asin(
 float(
 input("Enter a small number: ")
 )
 )
)
$ python3 asin.py
Enter a small number: 1
1.5707963267948966
$ python3 asin.py
Enter a small number: 4
Traceback (most recent call last):
   File "/home/rosuav/tmp/asin.py", line 4, in 
 math.asin(
ValueError: math domain error
$ python3 asin.py
Enter a small number: spam
Traceback (most recent call last):
   File "/home/rosuav/tmp/asin.py", line 5, in 
 float(
ValueError: could not convert string to float: 'spam'

Note that the line numbers correctly show the true cause of the
problem, despite both of them being ValueErrors. So if you have to
debug this sort of thing, make sure the key parts are on separate
lines (even if they're all one expression, as in this example), and
then the tracebacks should tell you what you need to know.



Yes, an excellent example to show newcomers to make use of 'the 
information *provided*' - take a deep breath and read through it all, 
picking-out the important information...



However, returning to "condense this into a single line", the 
frequently-seen coding is (in my experience, at least):


quantity = float( input( "How many would you like? " ) )

which would not produce the helpful distinction between 
line-numbers/function-calls which the above (better-formatted) code does!



Summarising (albeit IMHO):

- if relatively trivial/likely to be well-known: collect the calls into 
a chain, eg


user = user.strip().lower()

- otherwise use separate lines in order to benefit from the stack-trace

- (still saying) use separate assignments, rather than chaining more 
complex/lesser-known combinations


- ensure that the 'final' identifier is meaningful (and perhaps the 
first, and/or even an 'intermediate' if pertinent or kept for re-use later)


- perhaps re-use a single identifier-name as a temp-variable, if can 
reasonably 'get away with it'

(and not confuse simple minds, like yours-truly)


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


Re: Tkinter docs?

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 13:11, Rob Cliffe via Python-list
 wrote:
>
> I have recently started converting a large project to tkinter, starting
> with zero knowledge of tkinter.  (You are free to think: BAD IDEA. 😁)
> I am well aware that adopting a new tool always involves a learning
> curve, and that one is prone to think that things are more difficult
> than they are/should be, and to belly-ache about it, and that in a year
> from now I'll probably wonder what I'm fussing about.

Yes, I do think this is a bad idea, though not an abysmal one. I would
recommend first playing with tkinter in a dedicated UI-only project
before converting the main project to it. Your code in the scratch
project can be as messy as it likes, and then you learn from it before
tackling the big one :)

But your concerns about tkinter's documentation are, sadly,
well-founded. Since it's this weird system of thin wrappers around
Tcl/Tk, a lot of things are basically just "go read the Tk docs".
There are a few key concepts you'll need to get your head around, and
I can't go into details because I never truly got *my* head around
them... but mostly, the way that variables are used and what happens
when events fire.

Good luck with it. I'll be frank, building a GUI can be pretty hard...
I'm still unsure whether the best way is to use something like
tkinter, or to build a web app, pop up a browser window, and establish
a websocket to communicate between your JavaScript front end and your
Python back end. Yeah, that's how bad GUI building can be sometimes -
it is potentially *easier* to build two halves of your app in two
different languages than to make your GUI work the way you want it.

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