From pasokan at gmail.com  Tue Aug  1 01:43:40 2017
From: pasokan at gmail.com (Asokan Pichai)
Date: Tue, 1 Aug 2017 11:13:40 +0530
Subject: [Tutor] Recommended Python Compiler
In-Reply-To: <oloab1$20r$1@blaine.gmane.org>
References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com>
 <1285690201.2134862.1501453378125@mail.yahoo.com>
 <ollsfa$n7q$1@blaine.gmane.org>
 <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us>
 <oln8op$tr2$1@blaine.gmane.org> <oloab1$20r$1@blaine.gmane.org>
Message-ID: <CAB3TsCj5h8Svh0avZtqNoXFVmYQeX+iUA5R663573PoyWR2EZA@mail.gmail.com>

For a simple beginners editor -- geany is a great choice.

It can be used with minimal or no configuration/set up; and once
you know your way around  you can tweak it as much as you want.

It is easily installable on Debian/Ubuntu


-- 
Asokan Pichai
*-------------------*
We will find a way. Or, make one. (Hannibal)

From __peter__ at web.de  Tue Aug  1 03:06:55 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 01 Aug 2017 09:06:55 +0200
Subject: [Tutor] Python isn't working with Apache (Windows)
References: <BN6PR2201MB1121B3B0DA34DAE0117E5F7BFDB20@BN6PR2201MB1121.namprd22.prod.outlook.com>
Message-ID: <olp9a9$i05$1@blaine.gmane.org>

Christopher McGrath wrote:

> I am trying to run a simple python web script in a browser with apache. I
> have apache installed and running perfectly. I installed Ruby and Perl

> I had Python 3.6 installed before and tried to test with these

> I also tried with #!Q:\LifeForce\Python36-32\python.exe. This one works
> worked from Window Command, but didn?t work from web browser like PERL and
> RUBY. 

> I am trying to run directly from Apache htdoc dir. Not from cgi dir. I
> think something is wrong with the shebang line. This is the error output
> in the web browser: Internal Server Error
> The server encountered an internal error or misconfiguration and was
> unable to complete your request. Please contact the server administrator
> at postmaster at localhost to inform them of the time this error occurred,
> and the actions you performed just before this error. More information
> about this error may be available in the server error log. Additionally, a
> 500 Internal Server Error error was encountered while trying to use an
> ErrorDocument to handle the request. This is what is shown in Apache?s
> error log:
> [Mon Jul 31 01:06:54.266478 2017] [cgi:error] [pid 5156:tid 1688] [client
> [98.5.128.152:51723] malformed header from script 'test.py': Bad header:
> [Mon Jul 31 01:06:54.270479 2017] [authz_core:error] [pid 5156:tid 1688]
> [[client 98.5.128.152:51723] AH01630: client denied by server
> [configuration: C:/Apache24

It looks like Apache is already running your script. It just can't make 
sense of its output. The header has to be separated from the data by an 
empty line. In your script that line contains an extra space that you must 
remove.

> I also tried with #!Q:\LifeForce\Python36-32\python.exe. This one works
> worked from Window Command, but didn?t work from web browser like PERL and
> RUBY. 

> Nothing worked. I don?t have any idea anymore. Please help!
> This is the simple code:

#!Q:\LifeForce\Python36-32\python.exe
> print ("Content-type: text/html")
  print ("")
> print ("<html><head>")
> print ("")
> print ("</head><body>")
> print ("Hello Python.")
> print ("</body></html>")

Does it work after this small change?


From rampappula at gmail.com  Tue Aug  1 02:06:18 2017
From: rampappula at gmail.com (ramakrishna reddy)
Date: Mon, 31 Jul 2017 23:06:18 -0700
Subject: [Tutor] How sum() works in python
Message-ID: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>

Hi All,

I know

> sum([1,2,3]) returns 6.

But sum with [] 'empty list' as second parameter returns as below.

> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]
Can any one please explain this logic ? I searched in google but could not
find the suitable answer.

Thanks in advance.


Thanks,
Ram.

From alan.gauld at yahoo.co.uk  Tue Aug  1 04:33:38 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 1 Aug 2017 09:33:38 +0100
Subject: [Tutor] How sum() works in python
In-Reply-To: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
References: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
Message-ID: <olpecs$ijf$1@blaine.gmane.org>

On 01/08/17 07:06, ramakrishna reddy wrote:

>> sum([1,2,3]) returns 6.
> 
> But sum with [] 'empty list' as second parameter returns as below.
> 
>> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]

An interesting question, I wasn't aware that you could
add lists with sum.

However, the results seem clear enough. Let's start with the help()
description:
#################
Help on built-in function sum in module builtins:

sum(...)
    sum(iterable[, start]) -> value

    Return the sum of an iterable of numbers (NOT strings) plus
    the value of parameter 'start' (which defaults to 0).
    When the iterable is empty, return start.
#################

And lets see how it behaves with integers first:
>>> sum([1,2,3])   # use start default of 0
6
>>> sum([1,2,3],0) # use explicit start=0
6
>>> sum([1,2,3],1) # use start=1
7
>>> sum([1,2,3],9) # start = 9
15

So in each case we get the sum of the items in the iterable
plus the value of start. sum() is effectively doing

result = start
for n in iterable: result += n
return result

Now lets try using a list of lists:

>>> sum([ [1,2,3],[3,4,5] ])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'

We get a type error because the start uses 0 and we can't
add an int and a list. So let's provide a list as the
start value:

>>> sum([ [1,2,3],[3,4,5] ], [])
[1, 2, 3, 3, 4, 5]
>>>

We now get the behaviour you saw because it adds the
three lists together using the same algorithm as above.

And if we use a non-empty start it becomes even more clear:

>>> sum([ [1,2,3],[3,4,5] ], [42])
[42, 1, 2, 3, 3, 4, 5]

We could use tuples instead of lists and get the same result.

What is interesting is that if we try the same thing with
other iterables, such as a string, it doesn't work, even
though string addition is defined. There is obviously
some type checking taking place in there.

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



From __peter__ at web.de  Tue Aug  1 04:57:22 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 01 Aug 2017 10:57:22 +0200
Subject: [Tutor] How sum() works in python
References: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
Message-ID: <olpfpf$tc1$1@blaine.gmane.org>

ramakrishna reddy wrote:

> Hi All,
> 
> I know
> 
>> sum([1,2,3]) returns 6.
> 
> But sum with [] 'empty list' as second parameter returns as below.
> 
>> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]
> Can any one please explain this logic ? I searched in google but could not
> find the suitable answer.

sum() adds up whatever you feed it (unless it's a string). A simplified 
pure-python implementation is

>>> def mysum(iterable, start=0):
...     result = start
...     for value in iterable:
...         result = result + value
...     return result
... 

When you feed it a list of numbers

>>> mysum([1, 2, 3, 4])
10

it calculates the sum, when the list is empty it returns the start value

>>> mysum([])
0

...whatever it may be:

>>> mysum([], mysum)
<function mysum at 0x7fd5ee36a510>
>>> sum([], sum)
<built-in function sum>

When you feed it a list of lists it tries to add 0 + first_list and fails

>>> mysum([[1,2], [3,4]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in mysum
TypeError: unsupported operand type(s) for +: 'int' and 'list'

However when you provide a list as the start value that list and the lists 
in the `iterable` argument are concatenated

>>> mysum([[1,2], [3,4]], [])
[1, 2, 3, 4]
>>> mysum([[1, "a"], [3, 4.0]], [42])
[42, 1, 'a', 3, 4.0]

...because concatenation is what the + operator is written to do

>>> ["foo", "bar", "baz"] + ["ham", "spam"]
['foo', 'bar', 'baz', 'ham', 'spam']

for Python's built-in lists.

If you feed your own objects to sum() you are completely free how you 
implement + -- if you have it remove files from your hard drive then that's 
what sum() will do when you try to calculate the sum:

>>> class Remove(list):
...     def __radd__(self, other):
...         for name in self:
...             print("Deleting file", name)
... 
>>> sum([Remove(["important.txt", "keepsafe.doc"]), 
Remove(["nice_pic.jpg"])])
Deleting file important.txt
Deleting file keepsafe.doc
Deleting file nice_pic.jpg



From rakeshsharma14 at hotmail.com  Tue Aug  1 07:13:25 2017
From: rakeshsharma14 at hotmail.com (rakesh sharma)
Date: Tue, 1 Aug 2017 11:13:25 +0000
Subject: [Tutor] Error with sqlalchemy
Message-ID: <BMXPR01MB07913DF2BDF913C36D2437BBC8B30@BMXPR01MB0791.INDPRD01.PROD.OUTLOOK.COM>

Hi All


I am getting an error in python. Its a flask app that I am doing

I am getting the error

TypeError: utf_8_decode() argument 1 must be string or buffer, not long

at this point in the code

ship_schedules = ShipSchedule.query.all()

The schema definition is like that I gave below, there is no mismatch between the schema and the table definition in the mysql DB.

class ShipSchedule(Base):

    __tablename__ = 'ship_schedule'

    vessel_imo_no = Column(Integer, primary_key=True, nullable=False)
    commodity_product_code = Column(String, nullable=False)
    port_port_code = Column(String, nullable=False)
    cargo_quantity = Column(String, nullable=False)
    activity = Column(String, nullable=False)
    date_from = Column(Date, nullable=False)
    date_to = Column(Date, nullable=False)


"""
    Ship schedule schema
"""


class ShipScheduleSchema(Schema):
    vessel_imo_no = fields.Int(dump_only=True)
    commodity_product_code = fields.Str()
    port_port_code = fields.Str()
    cargo_quantity = fields.Int()
    activity = fields.Str()
    date_from = fields.Date()
    date_to = fields.Date()

the mysql table defintion is as follows


[cid:e101f2ac-60ca-426a-8e53-01afd9e9414d]


please help on this, do not know the whats causing the issue.

I dint find any good answers in stackoverflow as all points to schema mismatch

thanks

rakesh

From mats at wichmann.us  Tue Aug  1 09:38:56 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Tue, 1 Aug 2017 07:38:56 -0600
Subject: [Tutor] Error with sqlalchemy
In-Reply-To: <BMXPR01MB07913DF2BDF913C36D2437BBC8B30@BMXPR01MB0791.INDPRD01.PROD.OUTLOOK.COM>
References: <BMXPR01MB07913DF2BDF913C36D2437BBC8B30@BMXPR01MB0791.INDPRD01.PROD.OUTLOOK.COM>
Message-ID: <df863107-0d6d-97d2-ebe0-9fa99a2f25c3@wichmann.us>

On 08/01/2017 05:13 AM, rakesh sharma wrote:
> Hi All
> 
> 
> I am getting an error in python. Its a flask app that I am doing
> 
> I am getting the error
> 
> TypeError: utf_8_decode() argument 1 must be string or buffer, not long
> 
> at this point in the code
> 
> ship_schedules = ShipSchedule.query.all()
> 
> The schema definition is like that I gave below, there is no mismatch between the schema and the table definition in the mysql DB.
> 
> class ShipSchedule(Base):
> 
>     __tablename__ = 'ship_schedule'
> 
>     vessel_imo_no = Column(Integer, primary_key=True, nullable=False)
>     commodity_product_code = Column(String, nullable=False)
>     port_port_code = Column(String, nullable=False)
>     cargo_quantity = Column(String, nullable=False)
>     activity = Column(String, nullable=False)
>     date_from = Column(Date, nullable=False)
>     date_to = Column(Date, nullable=False)
> 
> 
> """
>     Ship schedule schema
> """
> 
> 
> class ShipScheduleSchema(Schema):
>     vessel_imo_no = fields.Int(dump_only=True)
>     commodity_product_code = fields.Str()
>     port_port_code = fields.Str()
>     cargo_quantity = fields.Int()
>     activity = fields.Str()
>     date_from = fields.Date()
>     date_to = fields.Date()
> 
> the mysql table defintion is as follows
> 
> 
> [cid:e101f2ac-60ca-426a-8e53-01afd9e9414d]

this is not viewable, at least not here.

you've potentially got an issue in your cargo quantity definition in the
two classes, possibly take a closer look at that (String vs fields.Int()).

this is a pretty specialized sort of query, probably the sqlalchemy
community would be more expert in this stuff (given you said you've
exhausted stackoverflow already). maybe they have knowledge of some
consistency-checking tool that could detect mismatches?

From arj.python at gmail.com  Tue Aug  1 04:26:24 2017
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Tue, 1 Aug 2017 12:26:24 +0400
Subject: [Tutor] Recommended Python Compiler
In-Reply-To: <CAB3TsCj5h8Svh0avZtqNoXFVmYQeX+iUA5R663573PoyWR2EZA@mail.gmail.com>
References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com>
 <1285690201.2134862.1501453378125@mail.yahoo.com>
 <ollsfa$n7q$1@blaine.gmane.org>
 <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us>
 <oln8op$tr2$1@blaine.gmane.org> <oloab1$20r$1@blaine.gmane.org>
 <CAB3TsCj5h8Svh0avZtqNoXFVmYQeX+iUA5R663573PoyWR2EZA@mail.gmail.com>
Message-ID: <CADrxXXkuNsRAQ78+0ZvtiBo4ime24mzpkc-k_NunukssOuc+Jw@mail.gmail.com>

Yes indeed geany is a nice editor. I used it when i was beginning and even
wrote a post about it, Feel free to check it !

https://abdurrahmaanjanhangeer.wordpress.com/2016/11/02/python-getting-rid-of-identation-errors-quickly-checking-for-errors-and-the-use-of-editors/

On Tue, Aug 1, 2017 at 9:43 AM, Asokan Pichai <pasokan at gmail.com> wrote:

> For a simple beginners editor -- geany is a great choice.
>
> It can be used with minimal or no configuration/set up; and once
> you know your way around  you can tweak it as much as you want.
>
> It is easily installable on Debian/Ubuntu
>
>
> --
> Asokan Pichai
> *-------------------*
> We will find a way. Or, make one. (Hannibal)
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From arj.python at gmail.com  Tue Aug  1 04:27:36 2017
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Tue, 1 Aug 2017 12:27:36 +0400
Subject: [Tutor] How sum() works in python
In-Reply-To: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
References: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
Message-ID: <CADrxXXnNwyg-U0x7satOve8xs4tJBAznxp=zKfRb2O4aF6SMuw@mail.gmail.com>

i guess it adds / sort of concatenates the list

On Tue, Aug 1, 2017 at 10:06 AM, ramakrishna reddy <rampappula at gmail.com>
wrote:

> Hi All,
>
> I know
>
> > sum([1,2,3]) returns 6.
>
> But sum with [] 'empty list' as second parameter returns as below.
>
> > sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]
> Can any one please explain this logic ? I searched in google but could not
> find the suitable answer.
>
> Thanks in advance.
>
>
> Thanks,
> Ram.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From rampappula at gmail.com  Tue Aug  1 04:48:36 2017
From: rampappula at gmail.com (ramakrishna reddy)
Date: Tue, 01 Aug 2017 08:48:36 +0000
Subject: [Tutor] How sum() works in python
In-Reply-To: <olpecs$ijf$1@blaine.gmane.org>
References: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
 <olpecs$ijf$1@blaine.gmane.org>
Message-ID: <CAOZWNskc00tJZaK=wSSg3ZE+_yJE1pbwnOscC=G_Gz68pyi+2A@mail.gmail.com>

nice explanation .. thanks

this cleared my doubt
>>> k = [20]
>>> for i in [[1,2,3],[3,4,5]]:
...     k += i
...
>>> k
[20, 1, 2, 3, 3, 4, 5]

On Tue, Aug 1, 2017 at 1:35 AM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 01/08/17 07:06, ramakrishna reddy wrote:
>
> >> sum([1,2,3]) returns 6.
> >
> > But sum with [] 'empty list' as second parameter returns as below.
> >
> >> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]
>
> An interesting question, I wasn't aware that you could
> add lists with sum.
>
> However, the results seem clear enough. Let's start with the help()
> description:
> #################
> Help on built-in function sum in module builtins:
>
> sum(...)
>     sum(iterable[, start]) -> value
>
>     Return the sum of an iterable of numbers (NOT strings) plus
>     the value of parameter 'start' (which defaults to 0).
>     When the iterable is empty, return start.
> #################
>
> And lets see how it behaves with integers first:
> >>> sum([1,2,3])   # use start default of 0
> 6
> >>> sum([1,2,3],0) # use explicit start=0
> 6
> >>> sum([1,2,3],1) # use start=1
> 7
> >>> sum([1,2,3],9) # start = 9
> 15
>
> So in each case we get the sum of the items in the iterable
> plus the value of start. sum() is effectively doing
>
> result = start
> for n in iterable: result += n
> return result
>
> Now lets try using a list of lists:
>
> >>> sum([ [1,2,3],[3,4,5] ])
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for +: 'int' and 'list'
>
> We get a type error because the start uses 0 and we can't
> add an int and a list. So let's provide a list as the
> start value:
>
> >>> sum([ [1,2,3],[3,4,5] ], [])
> [1, 2, 3, 3, 4, 5]
> >>>
>
> We now get the behaviour you saw because it adds the
> three lists together using the same algorithm as above.
>
> And if we use a non-empty start it becomes even more clear:
>
> >>> sum([ [1,2,3],[3,4,5] ], [42])
> [42, 1, 2, 3, 3, 4, 5]
>
> We could use tuples instead of lists and get the same result.
>
> What is interesting is that if we try the same thing with
> other iterables, such as a string, it doesn't work, even
> though string addition is defined. There is obviously
> some type checking taking place in there.
>
> HTH
> --
> 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
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From alan.gauld at yahoo.co.uk  Tue Aug  1 10:44:13 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 1 Aug 2017 15:44:13 +0100
Subject: [Tutor] Error with sqlalchemy
In-Reply-To: <BMXPR01MB07913DF2BDF913C36D2437BBC8B30@BMXPR01MB0791.INDPRD01.PROD.OUTLOOK.COM>
References: <BMXPR01MB07913DF2BDF913C36D2437BBC8B30@BMXPR01MB0791.INDPRD01.PROD.OUTLOOK.COM>
Message-ID: <olq43m$vvj$1@blaine.gmane.org>

On 01/08/17 12:13, rakesh sharma wrote:

> I am getting the error
> 
> TypeError: utf_8_decode() argument 1 must be string or buffer, not long

That's not too helpful out of context, can you show us more
of the error trace? Can you show us the method that generates
it? Do you have any indication about which field is generating
the error?

> at this point in the code
> 
> ship_schedules = ShipSchedule.query.all()

One line out of context doesn't really help.
I'm assuming query is a class attribute in
the inherited Base class? Do you have to create
any overridden methods/attribute values to
make it work for your subclass?

I can't comment on the schemas because I don't know MySql
or Flask's ORM well enough to understand what may be happening.
But a bit more detail on the actual code triggering the
error and the error message itself would certainly not hurt.

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



From guettliml at thomas-guettler.de  Tue Aug  1 10:54:40 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Tue, 1 Aug 2017 16:54:40 +0200
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
Message-ID: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>

I have a friend who is a talented shell script writer. He is a linux guru since
several years.

He asked me if "if __name__=='main':" is state of the art if you want
to translate a shell script to python.

I started to stutter and did not know how to reply.

I use Python since several years and I use console_script in entry_points of setup.py.

I am very unsure if this is the right way if you want to teach a new comers the joy of python.

In the current context we want to translate a bunch of shell scripts to python scripts.

What do you think?

Regards,
   Thomas G?ttler


-- 
Thomas Guettler http://www.thomas-guettler.de/

From zachary.ware+pytut at gmail.com  Tue Aug  1 13:59:53 2017
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Tue, 1 Aug 2017 12:59:53 -0500
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
Message-ID: <CAKJDb-M+=fwvAH_CW_K+=POshg==4G9cbhigywzBUg=DUyZPYA@mail.gmail.com>

On Tue, Aug 1, 2017 at 9:54 AM, Thomas G?ttler
<guettliml at thomas-guettler.de> wrote:
> I have a friend who is a talented shell script writer. He is a linux guru
> since
> several years.
>
> He asked me if "if __name__=='main':" is state of the art if you want
> to translate a shell script to python.
>
> I started to stutter and did not know how to reply.

The ~~correct~~ pedantic answer is "No, it's `if __name__ == '__main__':`" :)

> I use Python since several years and I use console_script in entry_points of
> setup.py.
>
> I am very unsure if this is the right way if you want to teach a new comers
> the joy of python.
>
> In the current context we want to translate a bunch of shell scripts to
> python scripts.
>
> What do you think?

It depends on whether you're packaging them up as real Python packages
(sdist, wheel, etc.) to be installed in site-packages or similar, or
if they're just going to be standalone scripts (single file with a
shebang, possibly not even a `.py` extension).  If the former, go for
the entry points.  If the latter, go for `if __name__ == '__main__':`.
And there's no real reason not to do both in the former case anyway;
it's very convenient to not have to install your script somehow to be
able to run it.

-- 
Zach

From kwpolska at gmail.com  Tue Aug  1 14:32:01 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Tue, 1 Aug 2017 20:32:01 +0200
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
Message-ID: <CAMw+j7J9MwTW7pFUfkFSnzxhOVFQ1Ayg3XtirTdWOnmGzkNtvQ@mail.gmail.com>

On 1 August 2017 at 16:54, Thomas G?ttler <guettliml at thomas-guettler.de> wrote:
> I have a friend who is a talented shell script writer. He is a linux guru
> since
> several years.
>
> He asked me if "if __name__=='main':" is state of the art if you want
> to translate a shell script to python.
>
> I started to stutter and did not know how to reply.
>
> I use Python since several years and I use console_script in entry_points of
> setup.py.
>
> I am very unsure if this is the right way if you want to teach a new comers
> the joy of python.
>
> In the current context we want to translate a bunch of shell scripts to
> python scripts.
>
> What do you think?
>
> Regards,
>   Thomas G?ttler
>
>
> --
> Thomas Guettler http://www.thomas-guettler.de/
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

Do both. If you?re making a package, create a __main__.py file as well
so your package is usable with `python -m somepackage`. On the other
hand, if you?re making things more akin to shell scripts, using just
entry_points makes stuff harder, because you need to install the code
(and write a setup.py), as opposed to just putting the script
somewhere in $PATH.

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From alan.gauld at yahoo.co.uk  Tue Aug  1 14:47:42 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 1 Aug 2017 19:47:42 +0100
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
Message-ID: <olqic7$253$1@blaine.gmane.org>

On 01/08/17 15:54, Thomas G?ttler wrote:

> He asked me if "if __name__=='main':" is state of the art if you want
> to translate a shell script to python.

It all depends what you plan to do with the script.
If you literally just want to translate a shell script such
that it will always be executed directly then you don't
even need an 'if name' clause, just hard code the script.

But if you plan in writing some functions that could be
reused by importing the script as a module then you really
should use 'if main'...

And if you intend to use your script only as a module
you should still use 'if name'... but this time call a
test function that runs some regression tests and/or
demo code.

But if you want to write a distributable package that
users can install into their Python infrastructure then
you should *additionally* create setup scripts with
entry points etc.

> you want to teach a new comers the joy of python.

For a newcomer I'd ignore packaging for now and focus
on the benefits of 'if name' over hard coding. One of the
great things about Python is how insanely easy it is to
create a file that can act as both a module and
executable. That can be crazy complex in some other
languages by comparison.


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



From dbosah at buffalo.edu  Tue Aug  1 14:48:19 2017
From: dbosah at buffalo.edu (Daniel Bosah)
Date: Tue, 1 Aug 2017 14:48:19 -0400
Subject: [Tutor] Python Daemons
Message-ID: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>

I'm following an online tutorial about threading. This is the code I've
used so far:

import socket
import threading
from queue import Queue



print_lock = threading.Lock()

target = 'pythonprogramming.net'

def portscan(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
       con = s.connect((target,port)) # con for connect
       with print_lock: # if sucessful run with statement
          print 'port', port, 'is open'
       con.close() # closes connection
    except:
           pass #if it doesn't work pass the method

def threader():
    while True:
        worker = q.get()
        portscan(worker)
        q.task_done
q = Queue()
for x in range(30):
    t = threading.Thread(target = threader() #creates a thread, gets
workers from q, set them to work on portscanning
    t.daemon() = True # want it to be a daemon
    t.start()
    #jobs = ports
for worker in range(1,101): # port zero invalid port
    q.put(worker) # puts worker to work
q.join() #waits till thread terminiates


    I don't know what a Daemon is, and I also don't know how to use it in
Python 2.7. Apparently its built in Python 3, but  I don't know how to use
it in Python 2.7. Any help would be appreciated.

From steve at pearwood.info  Tue Aug  1 20:49:09 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 10:49:09 +1000
Subject: [Tutor] Python Daemons
In-Reply-To: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>
References: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>
Message-ID: <20170802004909.GF3149@ando.pearwood.info>

Hi Daniel,

My responses below.

On Tue, Aug 01, 2017 at 02:48:19PM -0400, Daniel Bosah wrote:
> I'm following an online tutorial about threading. This is the code I've
> used so far:

Can you give us a link to the tutorial?

[...]
> def portscan(port):
>     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>     try:
>        con = s.connect((target,port)) # con for connect
>        with print_lock: # if sucessful run with statement
>           print 'port', port, 'is open'
>        con.close() # closes connection
>     except:
>            pass #if it doesn't work pass the method

I'm very concerned about that bare "except" line. I'm not absolutely 
saying that it is wrong, but in general bare excepts are a terrible 
idea.

https://realpython.com/blog/python/the-most-diabolical-python-antipattern/


> def threader():
>     while True:
>         worker = q.get()
>         portscan(worker)
>         q.task_done
> q = Queue()
> for x in range(30):
>     t = threading.Thread(target = threader() #creates a thread, gets
> workers from q, set them to work on portscanning
>     t.daemon() = True # want it to be a daemon
>     t.start()
>     #jobs = ports
> for worker in range(1,101): # port zero invalid port
>     q.put(worker) # puts worker to work
> q.join() #waits till thread terminiates
> 
> 
>     I don't know what a Daemon is, 

https://en.wikipedia.org/wiki/Daemon_(computing)




> and I also don't know how to use it in
> Python 2.7. Apparently its built in Python 3, but  I don't know how to use
> it in Python 2.7. Any help would be appreciated.

What happens when you try?



-- 
Steve

From steve at pearwood.info  Tue Aug  1 20:56:08 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 10:56:08 +1000
Subject: [Tutor] How sum() works in python
In-Reply-To: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
References: <CAOZWNs=0-A2O+SiCDdLBui7NJEHtL+Qo9zHOmfB7so2M1axheg@mail.gmail.com>
Message-ID: <20170802005606.GG3149@ando.pearwood.info>

On Mon, Jul 31, 2017 at 11:06:18PM -0700, ramakrishna reddy wrote:

> > sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5]

[] + [1,2,3] + [3,4,5]

returns [1, 2, 3, 3, 4, 5].


-- 
Steve

From ben+python at benfinney.id.au  Tue Aug  1 21:04:06 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 11:04:06 +1000
Subject: [Tutor] Python Daemons
References: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>
Message-ID: <85y3r2rda1.fsf@benfinney.id.au>

Daniel Bosah <dbosah at buffalo.edu> writes:

> I'm following an online tutorial about threading.

Can you point to it so we can understand your specific situation?

> I don't know what a Daemon is

The package ?python-daemon? is a library to build your program as a
daemon <URL:https://pypi.org/project/python-daemon/>.

The referenced PEP <URL:http://www.python.org/dev/peps/pep-3143>
describes what a daemon process is, and how the library provides what
you need to implement a daemon process.

> and I also don't know how to use it in Python 2.7. Apparently its
> built in Python 3, but I don't know how to use it in Python 2.7.

If you are learning Python, you should not use Python 2 unless there is
no other option. Python 2 is on the way out ? it will stop receiving all
support after 2020, and is already far behind Python 3.

There are, of course, tutorials for Python 3 and threading. For example
<URL:https://www.tutorialspoint.com/python3/python_multithreading.htm>.

> Any help would be appreciated.

I hope that helps.

-- 
 \                ?The supreme vice is shallowness.? ?Oscar Wilde, _De |
  `\                                                  Profundis_, 1897 |
_o__)                                                                  |
Ben Finney


From robertvstepp at gmail.com  Tue Aug  1 21:06:58 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 1 Aug 2017 20:06:58 -0500
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
Message-ID: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>

I had typed help(pow) in the interpreter and got:

<quote>
py3: help(pow)
Help on built-in function pow in module builtins:

pow(x, y, z=None, /)
    Equivalent to x**y (with two arguments) or x**y % z (with three arguments)

    Some types, such as ints, are able to use a more efficient algorithm when
    invoked using the three argument form.
</quote>

A quick scan of some of my Python books does not turn up the use of
"/" as a function argument.  I have a nagging feeling I've read about
this somewhere previously, but I cannot bring it to mind, and I have
yet to stumble on a search that brings up an answer (Yet.).

TIA!
-- 
boB

From steve at pearwood.info  Tue Aug  1 21:10:54 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 11:10:54 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
Message-ID: <20170802011054.GH3149@ando.pearwood.info>

On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote:

[...]
> I use Python since several years and I use console_script in entry_points 
> of setup.py.

What's console_script in entry_points of setup.py?

In particular, what does that have to do with writing an executable 
script?

setup.py is used for packaging Python code, so it can be distributed and 
installed easily.


> I am very unsure if this is the right way if you want to teach a new comers 
> the joy of python.

I think if you are teaching newcomers about packaging and setup.py, they 
will probably decide that Python is too complicated and hard to use.

For beginners, the best way to write a script is to just put your code 
in a file with a hashbang line.


#!/usr/local/bin/python3
print("Hello world!")



chmod the file to executable, and the script is ready.


For slightly more advanced use, move the script's executable code into a 
function, and test whether we're being imported or run as a script 
before calling the function:


#!/usr/local/bin/python3
def main():
    print("Hello world!")

if __name__ = '__main__':
    main()



This is considered best practice because it allows you to import the 
script for testing without the main() function automatically running.

When Python imports your script, the special variable __name__ will be 
set to the name of the script. When Python executes the script, __name__ 
will be set to the literal string '__main__'.



-- 
Steve

From ben+python at benfinney.id.au  Tue Aug  1 21:14:08 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 11:14:08 +1000
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
Message-ID: <85tw1qrctb.fsf@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> writes:

> A quick scan of some of my Python books does not turn up the use of
> "/" as a function argument.

The appearance of this in Python's documentation and dfunction signature
descriptions, without a clear description of what it means, is
troubling.

The best I can find is this informational draft PEP
<URL:https://www.python.org/dev/peps/pep-0457/>, which *proposes* it as
syntax for some future Python.

-- 
 \      ?The process by which banks create money is so simple that the |
  `\     mind is repelled.? ?John Kenneth Galbraith, _Money: Whence It |
_o__)                                       Came, Where It Went_, 1975 |
Ben Finney


From steve at pearwood.info  Tue Aug  1 21:15:35 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 11:15:35 +1000
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
Message-ID: <20170802011534.GI3149@ando.pearwood.info>

On Tue, Aug 01, 2017 at 08:06:58PM -0500, boB Stepp wrote:

> pow(x, y, z=None, /)
>     Equivalent to x**y (with two arguments) or x**y % z (with three arguments)

It means that the arguments are positional-only, the names "x", "y" and 
"z" are for documentation purposes only. You cannot write:

pow(x=2, y=3)

but only

pow(2, 3)


> A quick scan of some of my Python books does not turn up the use of
> "/" as a function argument.

Its quite new. Up until recently, the documentation didn't distinguish 
between function parameters which can take optional keywords and those 
that can't.


-- 
Steve

From ben+python at benfinney.id.au  Tue Aug  1 21:22:00 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 11:22:00 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info>
Message-ID: <85pocercg7.fsf@benfinney.id.au>

Steven D'Aprano <steve at pearwood.info> writes:

> On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote:
>
> [...]
> > I use Python since several years and I use console_script in
> > entry_points of setup.py.
>
> What's console_script in entry_points of setup.py?

It is an advanced feature in Setuptools, that allows defining a function
in the code base as the entry point for external use.

The ?console_scripts? entry points tell Setuptools to, at installation
time, create a wrapper script that invokes that function as a
command-line program.

    <URL:https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation>

> I think if you are teaching newcomers about packaging and setup.py,
> they will probably decide that Python is too complicated and hard to
> use.

Also, if you are teaching packaging and you introduce Setuptools
entry_points, they will probably decide that Setuptools is too
complicated and hard to use.

So I agree with Steven that teaching *newcomers to Python* how to use
Setuptools entry points is far too advanced level.

> For slightly more advanced use, move the script's executable code into
> a function, and test whether we're being imported or run as a script
> before calling the function:
>
>
> #!/usr/local/bin/python3
> def main():
>     print("Hello world!")
>
> if __name__ = '__main__':
>     main()

That's the best, I agree. Teach them early on to put all functionality
into functions, and (since the OP informs us these are accustomed to
writing command-line programs) the ?if __name__ == '__main__'? idiom
will be easy enough.

They should definitely learn it from you, along with the admonition to
*always* keep that block as small as possible.

Better than learning the idiom independently later on, and cramming half
their program into that block :-/

-- 
 \            ?But it is permissible to make a judgment after you have |
  `\    examined the evidence. In some circles it is even encouraged.? |
_o__)                    ?Carl Sagan, _The Burden of Skepticism_, 1987 |
Ben Finney


From ben+python at benfinney.id.au  Tue Aug  1 21:25:34 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 11:25:34 +1000
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
 <20170802011534.GI3149@ando.pearwood.info>
Message-ID: <85lgn2rca9.fsf@benfinney.id.au>

Steven D'Aprano <steve at pearwood.info> writes:

> Its quite new. Up until recently, the documentation didn't distinguish
> between function parameters which can take optional keywords and those
> that can't.

Where does the documentation describe this distinction? How is the
reader, coming across a link to documentation for a function, expected
to know what that symbol means in that context?

I am dismayed that the documentation has gone from describing function
signatures in Python syntax, to describing function signatures that
don't have the expected effect in Python code.

    Python 3.6.2 (default, Jul 17 2017, 16:44:45)
    [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def foo(lorem, /, ipsum):
      File "<stdin>", line 1
        def foo(lorem, /, ipsum):
                       ^
    SyntaxError: invalid syntax

-- 
 \              ?Ignorance more frequently begets confidence than does |
  `\           knowledge.? ?Charles Darwin, _The Descent of Man_, 1871 |
_o__)                                                                  |
Ben Finney


From robertvstepp at gmail.com  Tue Aug  1 22:03:54 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 1 Aug 2017 21:03:54 -0500
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <85lgn2rca9.fsf@benfinney.id.au>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
 <20170802011534.GI3149@ando.pearwood.info> <85lgn2rca9.fsf@benfinney.id.au>
Message-ID: <CANDiX9Jtkjs=LPm=nyqunSSUbbdCD5HkqUV7y0avX9GK9ADgqw@mail.gmail.com>

On Tue, Aug 1, 2017 at 8:25 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
> Steven D'Aprano <steve at pearwood.info> writes:
>
>> Its quite new. Up until recently, the documentation didn't distinguish
>> between function parameters which can take optional keywords and those
>> that can't.
>
> Where does the documentation describe this distinction? How is the
> reader, coming across a link to documentation for a function, expected
> to know what that symbol means in that context?

I also would like to know where this is documented.  The PEP Ben
linked to in his first response (PEP 457) is what I had looked at some
time in the past, but could not bring it to mind.  I obviously failed
the "expected to know ..." test, and I don't count myself a raw
beginner in Python anymore.  I imagine many would find the "/"
puzzling, perhaps even more experienced Python programmers?

> I am dismayed that the documentation has gone from describing function
> signatures in Python syntax, to describing function signatures that
> don't have the expected effect in Python code.
>
>     Python 3.6.2 (default, Jul 17 2017, 16:44:45)
>     [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
>     Type "help", "copyright", "credits" or "license" for more information.
>     >>> def foo(lorem, /, ipsum):
>       File "<stdin>", line 1
>         def foo(lorem, /, ipsum):
>                        ^
>     SyntaxError: invalid syntax

I gather from this example that "/" is *not* a syntactical element,
but is instead meant to augment natural English explanation.

Anyway, thanks very much Steve and Ben!

-- 
boB

From steve at pearwood.info  Tue Aug  1 23:49:35 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 13:49:35 +1000
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <85lgn2rca9.fsf@benfinney.id.au>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
 <20170802011534.GI3149@ando.pearwood.info> <85lgn2rca9.fsf@benfinney.id.au>
Message-ID: <20170802034935.GJ3149@ando.pearwood.info>

On Wed, Aug 02, 2017 at 11:25:34AM +1000, Ben Finney wrote:
> Steven D'Aprano <steve at pearwood.info> writes:
> 
> > Its quite new. Up until recently, the documentation didn't distinguish
> > between function parameters which can take optional keywords and those
> > that can't.
> 
> Where does the documentation describe this distinction? How is the
> reader, coming across a link to documentation for a function, expected
> to know what that symbol means in that context?

I don't know if it is already documented somewhere. I would have 
expected it to be listed in the Glossary under "parameter":

https://docs.python.org/3/glossary.html#term-parameter

but it isn't, even though positional-only parameters are listed. So 
that's a documentation bug.

But in general, there are certain conventions which the reader is just 
expected to know as background knowledge. Such as "->" meaning the 
return result, and [...] used for optional arguments:

    Help on class range in module builtins:

    class range(object)
     |  range(stop) -> range object
     |  range(start, stop[, step]) -> range object


That's from Python 3.5. But to prove this isn't a new issue, here's the 
start of the output of help(range) from Python 2.4:

    Help on built-in function range in module __builtin__:

    range(...)
        range([start,] stop[, step]) -> list of integers

As far as I know, the [...] convention for optional arguments is not 
documented anywhere.


> I am dismayed that the documentation has gone from describing function
> signatures in Python syntax, to describing function signatures that
> don't have the expected effect in Python code.

That's not new. If a naive user writes:

    range(1, 10[, 2])

they will get a SyntaxError. For that matter, if a naive user writes:

    range(stop)

they will probably get a NameError. A certain amount of domain knowledge 
has to be assumed.

"/" as a parameter is currently reserved for future use, and doesn't 
work in Python functions created with def or lambda. But it can be added 
to the signature for functions written in C.



-- 
Steve

From steve at pearwood.info  Tue Aug  1 23:51:39 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 13:51:39 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <85pocercg7.fsf@benfinney.id.au>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
Message-ID: <20170802035138.GK3149@ando.pearwood.info>

On Wed, Aug 02, 2017 at 11:22:00AM +1000, Ben Finney wrote:
> Steven D'Aprano <steve at pearwood.info> writes:
> 
> > On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote:
> >
> > [...]
> > > I use Python since several years and I use console_script in
> > > entry_points of setup.py.
> >
> > What's console_script in entry_points of setup.py?
> 
> It is an advanced feature in Setuptools, that allows defining a function
> in the code base as the entry point for external use.
> 
> The ?console_scripts? entry points tell Setuptools to, at installation
> time, create a wrapper script that invokes that function as a
> command-line program.
> 
>     <URL:https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation>

Thanks.

Now that I have learned that, I shall do my best to forget it :-)



-- 
Steve

From steve at pearwood.info  Tue Aug  1 23:58:34 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 13:58:34 +1000
Subject: [Tutor] Python Daemons
In-Reply-To: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu>
References: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu>
Message-ID: <20170802035834.GL3149@ando.pearwood.info>

On Tue, Aug 01, 2017 at 09:05:02PM -0400, dbosah wrote:
> Also here's the link to the tutorial
> https://youtu.be/WrtebUkUssc

That is clearly marked as "Python 3 Programming Tutorial". Why are you 
using Python 2? When you have a problem, you won't know if the problem 
is with your code, or a difference between Python 2 and 3. You're just 
making a rod for your own back by using Python 2.7 with a 3 tutorial.

Save yourself a lot of heartache and either stick to Python 2 tutorials 
or upgrade to Python 3.

-- 
Steve

From steve at pearwood.info  Wed Aug  2 00:08:43 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 2 Aug 2017 14:08:43 +1000
Subject: [Tutor] Python Daemons
In-Reply-To: <20170802010333.C542A27A8B56@smtp.buffalo.edu>
References: <20170802010333.C542A27A8B56@smtp.buffalo.edu>
Message-ID: <20170802040842.GM3149@ando.pearwood.info>

On Tue, Aug 01, 2017 at 09:03:30PM -0400, dbosah wrote:

> It usually says that it's an error.

Sorry, my crystal ball is at the shop being repaired and I don't know 
what "an error" means or how to fix it.

Please COPY AND PASTE the full text of the error, starting with the 
line "Traceback" and ending with the error message. Don't summarise it, 
or re-type it from memory.

The Python interpreter provides a lot of useful debugging information in 
these tracebacks. If you ignore it, and just say "An error occurred", it 
is impossible to tell what the error is and why it happened. Your code 
has over 20 lines in it. Assuming a minimum of ten things could go wrong 
with each line, that's 200 possible errors. At minimum.

It is a waste of my time, and confusing for you, to try to guess which 
of those is the error, when you have the information right there in 
front of you.

If you post the actual Traceback, we can help. If you don't, we can't.

> And I'm still confused by the definition of a Daemon. Is there another 
> resource you know that I can look at to break it down even further?

Have you tried googling for "daemon"?

In summary, and Ben will correct me if I'm wrong, a daemon is a computer 
program that runs as a background task. If you come from Windows, think 
of your anti-virus scanner which scans every file when you double-click 
on it, before the file runs. That will probably be a daemon, or the 
closest equivalent.


-- 
Steve

From ben+python at benfinney.id.au  Wed Aug  2 00:48:36 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 14:48:36 +1000
Subject: [Tutor] Python Daemons
References: <20170802010333.C542A27A8B56@smtp.buffalo.edu>
 <20170802040842.GM3149@ando.pearwood.info>
Message-ID: <85wp6mpobf.fsf@benfinney.id.au>

Steven D'Aprano <steve at pearwood.info> writes:

> On Tue, Aug 01, 2017 at 09:03:30PM -0400, dbosah wrote:

(I am not seeing your replies in this forum, dbosah. Please address your
replies to the mailing list ? not to an individual ? if you want the
discussion to continue.)

> > And I'm still confused by the definition of a Daemon.

The term is intended to distinguish a daemon from a typical process.

What understanding do you already have of a typical process on the
operating system? Does the term ?process? mean anything? How about
?terminal??

If you don't have a solid understanding of that, the definition is
unlikely to help because it's making distinctions below the level you're
used to thinking about.

Did the Wikipedia article help?

> In summary, and Ben will correct me if I'm wrong, a daemon is a
> computer program that runs as a background task.

That's not wrong, but ?background task? is vague. I don't know what to
assume about dbosah's understanding of processes to know how to help.

I'd say: what characterises a daemon process is that it has no
controlling terminal (it is ?detached? from the terminal that initiated
it).

-- 
 \      ?As soon as we abandon our own reason, and are content to rely |
  `\       upon authority, there is no end to our troubles.? ?Bertrand |
_o__)                                Russell, _Unpopular Essays_, 1950 |
Ben Finney


From eryksun at gmail.com  Wed Aug  2 02:59:30 2017
From: eryksun at gmail.com (eryk sun)
Date: Wed, 2 Aug 2017 06:59:30 +0000
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
Message-ID: <CACL+1asOnDr5OQXN61CDAcbsmVmb3vxjQecHR1aedqi+R4BLzA@mail.gmail.com>

On Wed, Aug 2, 2017 at 1:06 AM, boB Stepp <robertvstepp at gmail.com> wrote:
> I had typed help(pow) in the interpreter and got:
>
> <quote>
> py3: help(pow)
> Help on built-in function pow in module builtins:
>
> pow(x, y, z=None, /)
>     Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
>
>     Some types, such as ints, are able to use a more efficient algorithm when
>     invoked using the three argument form.
> </quote>
>
> A quick scan of some of my Python books does not turn up the use of
> "/" as a function argument.  I have a nagging feeling I've read about
> this somewhere previously, but I cannot bring it to mind, and I have
> yet to stumble on a search that brings up an answer (Yet.).

We discussed this syntax several months ago:

https://mail.python.org/pipermail/tutor/2017-February/thread.html#110344

From cs at cskk.id.au  Tue Aug  1 21:40:20 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 2 Aug 2017 11:40:20 +1000
Subject: [Tutor] Python Daemons
In-Reply-To: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>
References: <CAFSTFyU65OwT=e14U2utnVJP96B6wD6RpLXXY7xg6hS21EfgMw@mail.gmail.com>
Message-ID: <20170802014020.GA330@cskk.homeip.net>

On 01Aug2017 14:48, Daniel Bosah <dbosah at buffalo.edu> wrote:
>I'm following an online tutorial about threading. This is the code I've
>used so far:

In addition to the other replies, which mention the general computing "daemon" 
notion and the "python-daemon" library which aids making such python programs 
into well behaved daemons, I've got a couple of remarks about your code:

[...]
>def threader():
>    while True:
>        worker = q.get()
>        portscan(worker)
>        q.task_done

task_done is a method. So "q.task_done()". Your code will parse and run but the 
method will not get called; "q.task_done" with no brackets just mentioned the 
method without running it (sometimes a program wants to talk about a method or 
function but not call it right now).

>    t.daemon() = True # want it to be a daemon

The Thread.daemon is a property, not a method. So you set it like this:

    t.daemon = True

In the context of a thread, the daemon attribute implies that the daemon is a 
"worker" process, which does not need special shutdown. When your program ends, 
the Python runtime does not actually terminate until all _non_ damon Threads 
have finished. By marking a Thread as a daemon you're saying that its activity 
is not important after program exit. This is probably not the case for your 
tutorial task.

Like others, I recommend learning Python 3. It is broadly the same language but 
it is current.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From arj.python at gmail.com  Tue Aug  1 23:35:14 2017
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Wed, 2 Aug 2017 07:35:14 +0400
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <olqic7$253$1@blaine.gmane.org>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <olqic7$253$1@blaine.gmane.org>
Message-ID: <CADrxXXkWAbPjkgjega6Wc+KNNp7T_=PV6_51Mi+cHpBspeLyXg@mail.gmail.com>

what difference do you make between python scripts and python code files?

are codes relating to file manipulation called scripts?

Abdur-Rahmaan Janhangeer,
Mauritius
abdurrahmaanjanhangeer.wordpress.com

On 1 Aug 2017 22:48, "Alan Gauld via Tutor" <tutor at python.org> wrote:

> On 01/08/17 15:54, Thomas G?ttler wrote:
>
> > He asked me if "if __name__=='main':" is state of the art if you want
> > to translate a shell script to python.
>
> It all depends what you plan to do with the script.
> If you literally just want to translate a shell script such
> that it will always be executed directly then you don't
> even need an 'if name' clause, just hard code the script.
>
> But if you plan in writing some functions that could be
> reused by importing the script as a module then you really
> should use 'if main'...
>
> And if you intend to use your script only as a module
> you should still use 'if name'... but this time call a
> test function that runs some regression tests and/or
> demo code.
>
> But if you want to write a distributable package that
> users can install into their Python infrastructure then
> you should *additionally* create setup scripts with
> entry points etc.
>
> > you want to teach a new comers the joy of python.
>
> For a newcomer I'd ignore packaging for now and focus
> on the benefits of 'if name' over hard coding. One of the
> great things about Python is how insanely easy it is to
> create a file that can act as both a module and
> executable. That can be crazy complex in some other
> languages by comparison.
>
>
> --
> 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
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From dbosah at buffalo.edu  Tue Aug  1 21:05:02 2017
From: dbosah at buffalo.edu (dbosah)
Date: Tue, 01 Aug 2017 21:05:02 -0400
Subject: [Tutor] Python Daemons
Message-ID: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu>

Also here's the link to the tutorial
https://youtu.be/WrtebUkUssc
-------- Original message --------From: Steven D'Aprano <steve at pearwood.info> Date: 8/1/17  8:49 PM  (GMT-05:00) To: tutor at python.org Subject: Re: [Tutor] Python Daemons 
Hi Daniel,

My responses below.

On Tue, Aug 01, 2017 at 02:48:19PM -0400, Daniel Bosah wrote:
> I'm following an online tutorial about threading. This is the code I've
> used so far:

Can you give us a link to the tutorial?

[...]
> def portscan(port):
>???? s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>???? try:
>??????? con = s.connect((target,port)) # con for connect
>??????? with print_lock: # if sucessful run with statement
>?????????? print 'port', port, 'is open'
>??????? con.close() # closes connection
>???? except:
>??????????? pass #if it doesn't work pass the method

I'm very concerned about that bare "except" line. I'm not absolutely 
saying that it is wrong, but in general bare excepts are a terrible 
idea.

https://realpython.com/blog/python/the-most-diabolical-python-antipattern/


> def threader():
>???? while True:
>???????? worker = q.get()
>???????? portscan(worker)
>???????? q.task_done
> q = Queue()
> for x in range(30):
>???? t = threading.Thread(target = threader() #creates a thread, gets
> workers from q, set them to work on portscanning
>???? t.daemon() = True # want it to be a daemon
>???? t.start()
>???? #jobs = ports
> for worker in range(1,101): # port zero invalid port
>???? q.put(worker) # puts worker to work
> q.join() #waits till thread terminiates
> 
> 
>???? I don't know what a Daemon is, 

https://en.wikipedia.org/wiki/Daemon_(computing)




> and I also don't know how to use it in
> Python 2.7. Apparently its built in Python 3, but? I don't know how to use
> it in Python 2.7. Any help would be appreciated.

What happens when you try?



-- 
Steve
_______________________________________________
Tutor maillist? -? Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

From alan.gauld at yahoo.co.uk  Wed Aug  2 05:14:47 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 2 Aug 2017 10:14:47 +0100
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <CADrxXXkWAbPjkgjega6Wc+KNNp7T_=PV6_51Mi+cHpBspeLyXg@mail.gmail.com>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <olqic7$253$1@blaine.gmane.org>
 <CADrxXXkWAbPjkgjega6Wc+KNNp7T_=PV6_51Mi+cHpBspeLyXg@mail.gmail.com>
Message-ID: <ols561$la$1@blaine.gmane.org>

On 02/08/17 04:35, Abdur-Rahmaan Janhangeer wrote:
> what difference do you make between python scripts and python code files?
> 

Not much. Scripts are a concept more than a defined term,
they often refer to executable programs written in a
"scripting language" - which is usually an interpreted
language, like Python. Scripts traditionally coordinate
the actions of other, external programs, but as scripting
languages get more powerful they increasingly do all
the work themselves.

Code files covers any file containing code. Thus a
script is a subset of code file since it contains code.
But code files are not all executable, some are modules
to be imported by other code files (including scripts).

> are codes relating to file manipulation called scripts?

Not necessarily. Scripts tend to be shorter, comparatively
simple programs, similar to OS utilities. So they might
manipulate files, or they may tweak environment or
network settings etc. But some programs that manipulate
files are much more complex than that (think of a web
server) and would not normally be called scripts.

But it is a very vague area, the naming of scripts,
programs, applications, systems, modules, packages,
libraries etc. There are no clear definitions of
where one stops and the next begins.

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



From guettliml at thomas-guettler.de  Wed Aug  2 05:00:48 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Wed, 2 Aug 2017 11:00:48 +0200
Subject: [Tutor] __main__.py file Was: if __name__=='main' vs entry points:
 What to teach new comers?
In-Reply-To: <CAMw+j7J9MwTW7pFUfkFSnzxhOVFQ1Ayg3XtirTdWOnmGzkNtvQ@mail.gmail.com>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <CAMw+j7J9MwTW7pFUfkFSnzxhOVFQ1Ayg3XtirTdWOnmGzkNtvQ@mail.gmail.com>
Message-ID: <e7bb10bd-0775-49de-36c1-56d6a6ae4c6a@thomas-guettler.de>


> Do both. If you?re making a package, create a __main__.py file as well
> so your package is usable with `python -m somepackage`. On the other
> hand, if you?re making things more akin to shell scripts, using just
> entry_points makes stuff harder, because you need to install the code
> (and write a setup.py), as opposed to just putting the script
> somewhere in $PATH.
> 

Up to now I never did this. Maybe I will do this in the future.

thank you,
   Thomas G?ttler

-- 
Thomas Guettler http://www.thomas-guettler.de/

From guettliml at thomas-guettler.de  Wed Aug  2 05:03:05 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Wed, 2 Aug 2017 11:03:05 +0200
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <CADrxXXkWAbPjkgjega6Wc+KNNp7T_=PV6_51Mi+cHpBspeLyXg@mail.gmail.com>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <olqic7$253$1@blaine.gmane.org>
 <CADrxXXkWAbPjkgjega6Wc+KNNp7T_=PV6_51Mi+cHpBspeLyXg@mail.gmail.com>
Message-ID: <dc9db907-0845-99dc-dfca-cae97346b57c@thomas-guettler.de>



Am 02.08.2017 um 05:35 schrieb Abdur-Rahmaan Janhangeer:
> what difference do you make between python scripts and python code files?
> 
> are codes relating to file manipulation called scripts?

Do you ask this question all people on this list, or only one particular person?

I don't know the difference between python scripts and python code files.

Regards,
   thomas

-- 
Thomas Guettler http://www.thomas-guettler.de/

From guettliml at thomas-guettler.de  Wed Aug  2 05:06:37 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Wed, 2 Aug 2017 11:06:37 +0200
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <20170802035138.GK3149@ando.pearwood.info>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
Message-ID: <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>



Am 02.08.2017 um 05:51 schrieb Steven D'Aprano:
> On Wed, Aug 02, 2017 at 11:22:00AM +1000, Ben Finney wrote:
>> Steven D'Aprano <steve at pearwood.info> writes:
>>
>>> On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote:
>>>
>>> [...]
>>>> I use Python since several years and I use console_script in
>>>> entry_points of setup.py.
>>>
>>> What's console_script in entry_points of setup.py?
>>
>> It is an advanced feature in Setuptools, that allows defining a function
>> in the code base as the entry point for external use.
>>
>> The ?console_scripts? entry points tell Setuptools to, at installation
>> time, create a wrapper script that invokes that function as a
>> command-line program.
>>
>>      <URL:https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation>
> 
> Thanks.
> 
> Now that I have learned that, I shall do my best to forget it :-)

Maybe I am doing something wrong.  I was proud because I did use ?console_scripts? entry points.
I thought this is the right way of doing it. Doing things the right way always makes my feel so very good :-)

Regards,
   Thomas


-- 
Thomas Guettler http://www.thomas-guettler.de/

From mats at wichmann.us  Wed Aug  2 07:59:25 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Wed, 2 Aug 2017 05:59:25 -0600
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <85tw1qrctb.fsf@benfinney.id.au>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
 <85tw1qrctb.fsf@benfinney.id.au>
Message-ID: <214f1cdf-9508-8055-6170-c3b27978f2be@wichmann.us>

On 08/01/2017 07:14 PM, Ben Finney wrote:
> boB Stepp <robertvstepp at gmail.com> writes:
> 
>> A quick scan of some of my Python books does not turn up the use of
>> "/" as a function argument.
> 
> The appearance of this in Python's documentation and dfunction signature
> descriptions, without a clear description of what it means, is
> troubling.
> 
> The best I can find is this informational draft PEP
> <URL:https://www.python.org/dev/peps/pep-0457/>, which *proposes* it as
> syntax for some future Python.
> 

Yes, this is kind of interesting.

So it looks like it has been introduced internally to help with
introspection, but has not been introduced in documentation.

Old Python did this:

>>> help(pow)
pow(...)
    pow(x, y[, z]) -> number

new Python does this:

>>> pow(x, y, z=None, /)


Documentation still says this:

 pow(x, y[, z])

While the PEP suggested standardizing on not only the
end-of-positional-only parameters marker but also on the brackets to
show optional positional-only parameters, apparently the implementation
has not done the latter and has instead undone the brackets (at least in
this example) and gone to a different syntax which looks like a keyword
parameter but which you can infer is not because of the presence of the
marker somewhere to its right.


Fine.

So now it looks like the old advice of "if in doubt, ask Python itself"
should be tempered with "... although the response may use syntax that
is not documented anywhere and might confuse you"

Sorry, bad night, I shouldn't be sniping but it's hard to resist.

From robertvstepp at gmail.com  Wed Aug  2 08:30:26 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 2 Aug 2017 07:30:26 -0500
Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"?
In-Reply-To: <CACL+1asOnDr5OQXN61CDAcbsmVmb3vxjQecHR1aedqi+R4BLzA@mail.gmail.com>
References: <CANDiX9Ks_fV2U-uwVij1tFavOqGYLkaxBtNuB+hLQ0t34vOSYA@mail.gmail.com>
 <CACL+1asOnDr5OQXN61CDAcbsmVmb3vxjQecHR1aedqi+R4BLzA@mail.gmail.com>
Message-ID: <CANDiX9+HUNbHcgoDBmPsMG-s9D=ik0GK8oXPizFhXWjvZsaKUw@mail.gmail.com>

On Wed, Aug 2, 2017 at 1:59 AM, eryk sun <eryksun at gmail.com> wrote:
> On Wed, Aug 2, 2017 at 1:06 AM, boB Stepp <robertvstepp at gmail.com> wrote:

>> A quick scan of some of my Python books does not turn up the use of
>> "/" as a function argument.  I have a nagging feeling I've read about
>> this somewhere previously, but I cannot bring it to mind, and I have
>> yet to stumble on a search that brings up an answer (Yet.).
>
> We discussed this syntax several months ago:
>
> https://mail.python.org/pipermail/tutor/2017-February/thread.html#110344

Heavy sigh.  Thus why I felt I "had read about this".  I guess this
bit of knowledge did not stick very well!

Studying Python off and on, then taking days, weeks or even months off
before the next bit of studying is not an effective way to retain
knowledge.  But that's my life currently.

Thanks, Eryk.


-- 
boB

From ben+python at benfinney.id.au  Wed Aug  2 08:48:39 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 02 Aug 2017 22:48:39 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info>
 <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
Message-ID: <85k22mp23c.fsf@benfinney.id.au>

Thomas G?ttler <guettliml at thomas-guettler.de> writes:

> Maybe I am doing something wrong.  I was proud because I did use
> ?console_scripts? entry points.

Did someone lead you to believe it was wrong? Setuptools console_scripts
entry points are a good tool.

My point was that it is an *advanced* tool, difficult to use and also
difficult to explain because the concepts are advanced.

What's wrong is not that someone should learn and use this tool; what's
wrong IMO is to introduce newcomers to use this tool as their first way
to create command-line programs.

> I thought this is the right way of doing it. Doing things the right
> way always makes my feel so very good :-)

Continue using Setuptools entry points with my blessing.

-- 
 \            ?Technology is neither good nor bad; nor is it neutral.? |
  `\                       ?Melvin Kranzberg's First Law of Technology |
_o__)                                                                  |
Ben Finney


From steve at pearwood.info  Wed Aug  2 10:57:41 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 3 Aug 2017 00:57:41 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <85k22mp23c.fsf@benfinney.id.au>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au>
Message-ID: <20170802145741.GN3149@ando.pearwood.info>

On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote:
> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
> 
> > Maybe I am doing something wrong.  I was proud because I did use
> > ?console_scripts? entry points.
> 
> Did someone lead you to believe it was wrong? Setuptools console_scripts
> entry points are a good tool.
> 
> My point was that it is an *advanced* tool, difficult to use and also
> difficult to explain because the concepts are advanced.

Can you explain the use-case for when somebody might want to use 
console_scripts entry points?

I have a module with a main() function and an "if __name__ == ..." 
guard. Under what circumstances is that not sufficient, and I would want 
console_scripts?





-- 
Steve

From wolfgang.maier at biologie.uni-freiburg.de  Wed Aug  2 12:06:24 2017
From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier)
Date: Wed, 2 Aug 2017 18:06:24 +0200
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <20170802145741.GN3149@ando.pearwood.info>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
Message-ID: <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>

On 08/02/2017 04:57 PM, Steven D'Aprano wrote:
> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote:
>> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
>>
>>> Maybe I am doing something wrong.  I was proud because I did use
>>> ?console_scripts? entry points.
>>
>> Did someone lead you to believe it was wrong? Setuptools console_scripts
>> entry points are a good tool.
>>
>> My point was that it is an *advanced* tool, difficult to use and also
>> difficult to explain because the concepts are advanced.
> 
> Can you explain the use-case for when somebody might want to use
> console_scripts entry points?
> 
> I have a module with a main() function and an "if __name__ == ..."
> guard. Under what circumstances is that not sufficient, and I would want
> console_scripts?
> 

If you install things using pip/setuptools and have defined a
console_scripts entry point for it, then the corresponding wrapper
script will be installed in whatever is considered the scripts directory
at install time on that machine. With a bit of luck the entry point will
thus be executable directly without any end-user intervention (like
adding folders to $PATH and chmodding files).
Personally, I always found it straightforward to write the wrapper
script myself, then define this as a 'scripts' file in the package
layout of my setup.py, but people's MMV.


From tmrsg11 at gmail.com  Wed Aug  2 15:01:31 2017
From: tmrsg11 at gmail.com (C W)
Date: Wed, 2 Aug 2017 15:01:31 -0400
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
Message-ID: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>

Dear list,

I am a little confused about why Tuple can be sorted.

Suppose I have the following,

> aTuple = (9, 3, 7, 5)
> sorted(aTuple)
[3, 5, 7, 9]

Why is it ok to sort a the class tuple? If it is invariant by nature, then
wouldn't applying a function on it yield an error?

Thanks!

From mats at wichmann.us  Wed Aug  2 15:22:13 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Wed, 02 Aug 2017 13:22:13 -0600
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
In-Reply-To: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
References: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
Message-ID: <86977F27-85E5-4246-8757-96407F3EC9BB@wichmann.us>

it generated a new object, did not change the original. hint: notice the output is a list, not a tuple!

On August 2, 2017 1:01:31 PM MDT, C W <tmrsg11 at gmail.com> wrote:
>Dear list,
>
>I am a little confused about why Tuple can be sorted.
>
>Suppose I have the following,
>
>> aTuple = (9, 3, 7, 5)
>> sorted(aTuple)
>[3, 5, 7, 9]
>
>Why is it ok to sort a the class tuple? If it is invariant by nature,
>then
>wouldn't applying a function on it yield an error?
>
>Thanks!
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

From boriscobizaro8 at gmail.com  Wed Aug  2 15:53:05 2017
From: boriscobizaro8 at gmail.com (Borisco Bizaro)
Date: Wed, 2 Aug 2017 12:53:05 -0700
Subject: [Tutor] Tutor Digest, Vol 161, Issue 42
Message-ID: <CAKE=nh7ihgz_2KLjbJy-yJvy4=cdExQ8E5ymGrJcJurN_OsUFw@mail.gmail.com>

I try this using loop but could not stop by pressing a key and could not
give total price please help me
On Jul 31, 2017 13:07, boriscobizaro8 at gmail.com wrote:

print"\n welcome to progrom that print total price\n"
a=int(input("enter the first price: "))
b=int(input ("enter another price: "))
c=int(input ("enter another price: "))
d=int(input ("enter another price: "))
f=int(input ("enter another price: "))
g=int(input ("enter another price: "))
h=int(input ("enter another price: "))
total=a+b+c+d+f+g+h
print"\n totol",a+b+c+d+f+g+h
print("\n\n press the o key to exit ")
This is what I did but could not be able to used while loop
On Jul 30, 2017 23:44, <tutor-request at python.org> wrote:

Send Tutor mailing list submissions to
        tutor at python.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://mail.python.org/mailman/listinfo/tutor
or, via email, send a message with subject or body 'help' to
        tutor-request at python.org

You can reach the person managing the list at
        tutor-owner at python.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Tutor digest..."

Today's Topics:

   1. Re: Tutor Digest, Vol 161, Issue 41 (Borisco Bizaro)
   2. Re: Tutor Digest, Vol 161, Issue 41 (Alan Gauld)
   3. Re: Tutor Digest, Vol 161, Issue 33 (Borisco Bizaro)


---------- Forwarded message ----------
From: Borisco Bizaro <boriscobizaro8 at gmail.com>
To: tutor at python.org
Cc:
Bcc:
Date: Sun, 30 Jul 2017 11:50:22 -0700
Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 41
Please I have been ask to write python code that ask user to enter a price
continuetly until key press to and give the total amount of price I have
enter using while loop I don't know how to go about it,please help me
On Jul 29, 2017 17:00, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
> Today's Topics:
>
>    1. Installing NUMPY (David Torres)
>
>
> ---------- Forwarded message ----------
> From: David Torres <davidtorres7888 at gmail.com>
> To: tutor at python.org
> Cc:
> Bcc:
> Date: Fri, 28 Jul 2017 15:10:53 -0500
> Subject: [Tutor] Installing NUMPY
> Hello,
> I am having trouble executing a scripty that imports numpy. I have a
> feeling its because I had an old version of Numpy when I was using python
> 2.7. I am now using Pyhton 3X and I am getting the following error when I
> execute the program:::
>
>
> ImportError:
> Importing the multiarray numpy extension module failed.  Most
> likely you are trying to import a failed build of numpy.
> If you're working with a numpy git repo, try `git clean -xdf` (removes all
> files not under version control).  Otherwise reinstall numpy.
>
> Original error was: DLL load failed: The specified procedure could not be
> found.
>
>
>
> Please let me know if we can email each other or call. I would appreciate
> your help, I am very desperate! Thanks
> David A. Torres
> GitHub : https://github.com/dav1dt0rres
> -Man lives like a robot: mechanically efficient, but with no awareness.
> Department of Computer Science
>
>
>
> Department of Mathematics
> Department of Economics
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>



---------- Forwarded message ----------
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Cc:
Bcc:
Date: Sun, 30 Jul 2017 23:40:57 +0100
Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 41
On 30/07/17 19:50, Borisco Bizaro wrote:
> Please I have been ask to write python code that ask user to enter a price
> continuetly until key press to and give the total amount of price I have
> enter using while loop I don't know how to go about it

First of all, please do not send the whole digest to the list
 - some people pay by the byte and we've all seen it already.

Second, we solve programming challenges by breaking them down
into small parts and solving each part.

Third we don't do homework for you, but we can point you
in the right direction.

So, looking at your problem...

> ...write python code that ask user to enter a price

Do you know how to do that bit? get the usr to enter
a price and store (or print) the value?

> continuetly until key press

We'll come back to this.

> to and give the total amount of price

Do you know how to get the total of a list of prices?
For exanmple if I say

prices = [12, 13.00, 24.50. 17. 5.30]

Can you print the total of prices?

> enter using while loop

This ties in with the earlier requirement:

> enter using while loop
> continuously until key press

Lets assume the "keypress" is 0.
Do you know how to write a while loop that terminates
when an input value is 0?

Let us know the answers and we can point you
a little further towards solving the problem.

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





---------- Forwarded message ----------
From: Borisco Bizaro <boriscobizaro8 at gmail.com>
To: tutor at python.org
Cc:
Bcc:
Date: Sun, 30 Jul 2017 15:36:07 -0700
Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 33
Please I have been ask to write python code that ask user to enter a price
continuetly until key press to and give the total amount of price I have
enter using while loop I don't know how to go about it,please help me
This is what I have done,
untitled
a=1
b=2
while a<b:
  input ("enter another price :")
print"\n\n press 0 key to stop"
On Jul 24, 2017 01:06, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
> Today's Topics:
>
>    1. Fwd: Re:  Python Help (Alan Gauld)
>    2. Fwd: Re:  Python Help (Alan Gauld)
>    3. Python3 Help (Brandon Anderson)
>    4. class newbie (Michael C)
>
>
> ---------- Forwarded message ----------
> From: Alan Gauld <alan.gauld at yahoo.co.uk>
> To: tutor <tutor at python.org>
> Cc:
> Bcc:
> Date: Sun, 23 Jul 2017 21:45:45 +0100
> Subject: [Tutor] Fwd: Re: Python Help
>
> Forwarding to list,
> please use ReplyAll or ReplyList when responding to the list.
>
>
> -------- Forwarded Message --------
>
> I also tried the correct command for the mac ox s in terminal shell,
> running:
>
> Jims-MacBook-Pro-2:~ Jim$
> PYTHONPATH="/Users/Jim/Documents/illustris_python:$PYTHONPATH
>
> > export PYTHONPATH
>
>
> no error messages there but it is still not finding the module through
> python.
>
> Winonah
>
>
> On Sun, Jul 23, 2017 at 1:34 PM, Winonah Ojanen <winonah1992 at gmail.com
> <mailto:winonah1992 at gmail.com>> wrote:
>
>     I did use the pip command and am attempting to add the files to my
>     python path. I used
>      import sys
>     sys.path.append("/Users/Jim/Documents/illustris_python")
>
>     and that worked. I even checked to make sure the files were there
>
>
>     import sys
>     print (sys.path)
>
>     ['', '/Users/Jim/anaconda/lib/python36.zip',
>     '/Users/Jim/anaconda/lib/python3.6',
>     '/Users/Jim/anaconda/lib/python3.6/lib-dynload',
>     '/Users/Jim/anaconda/lib/python3.6/site-packages',
>     '/Users/Jim/anaconda/lib/python3.6/site-packages/
> Sphinx-1.5.6-py3.6.egg',
>     '/Users/Jim/anaconda/lib/python3.6/site-packages/aeosa',
>     '/Users/Jim/anaconda/lib/python3.6/site-packages/
> setuptools-27.2.0-py3.6.egg',
>     '/Users/Jim/anaconda/lib/python3.6/site-packages/IPython/extensions',
>     '/Users/Jim/.ipython', 'Users/Jim/Documents/illustris_python']
>
>     the file is clearly there but when i try to do import
>     illustris_python as il it still can't find the module.
>
>
> Note that only shows the folder is in the path.
>
> What does an 'ls' listing reveal as to the contents of the folder?
> Is there a file called illustris_python.py? or maybe illustris_python.pyc?
>
>
>
>     I also figured that I need to manually export to python path so i
> tried:
>     export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/
>       File "<ipython-input-14-30d153a77da5>", line 1
>         export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_
> python/
>                         ^
>     SyntaxError: invalid syntax
>
>     I got invalid syntax... using a mac os x
>
>     I tried typing in terminal open .bash_profile and telling it to
>     export the python path in there like some others recommended but in
>     terminal it is giving me an error message for that... it must not be
>     the right command for the shell.
>
>     Winonah
>
>     On Sat, Jul 22, 2017 at 9:34 PM, Cameron Simpson <cs at zip.com.au
>     <mailto:cs at zip.com.au>> wrote:
>
>         On 23Jul2017 00:20, Alan Gauld <alan.gauld at yahoo.co.uk
>         <mailto:alan.gauld at yahoo.co.uk>> wrote:
>
>             On 22/07/17 19:14, Winonah Ojanen wrote:
>
>                 using python with anaconda in jupiter notebook. However,
>                 I am having
>
>
>             Usual caveat: The tutor list is targeted at the standard
> library
>             so any help for non standard library modules is best sought
> from
>             the library support fora. In this case that includes the
>             SciPy forum
>             and any illustris one.
>
>
>         Though arguably the OP's problem is an import issue, not really
>         module specific.
>
>             That having been said, I'll take a guess...
>
>                 $ mkdir Illustris-3
>                 $ mkdir Illustris-3/groups_135
>
>             Are these folders in your PYTHONPATH? If not Python will not
>             find them.
>
>                 import illustris_python as il
>                 ------------------------------
> ---------------------------------------------
>                 ModuleNotFoundError                       Traceback
>                 (most recent call last)
>
>
>         The OP cded into the new dir; I'd normally expect things to be
>         found if the module was a local file/dir. However...
>
>                 For some reason the computer is not recognizing this as
>                 a file on my
>                 computer. The CCA folks says this is a coding problem
>                 and not an illustris
>                 problem. any ideas to get me past this? I may also need
>                 help getting
>                 farther into the download process.
>
>
>         I just ran the OP's download command:
>
>          wget -nd -nc -nv -e robots=off -l 1 -r -A hdf5
>         --content-disposition --header="API-Key:
>         d522db2e1b33e36d3b365cc9ac1c2c5d"
>         "http://www.illustris-project.org/api/Illustris-3/files/
> groupcat-135/?format=api
>         <http://www.illustris-project.org/api/Illustris-3/files/
> groupcat-135/?format=api>"
>
>         This doesn't seem to download any Python code at all. It does
>         get a couple of HDF files, presumably with data to work with.
>
>         So the issue is initially that the module isn't present
>         anywhere. Looking at the instructions cited
>         <http://www.illustris-project.org/data/docs/scripts/
>         <http://www.illustris-project.org/data/docs/scripts/>>, they
>         only cover fetching som data and working; they presume the
>         software is already present. I don't immediately see actual
>         software installation instructions, and it is not presented in
> PyPI.
>
>         Most like the OP will have to install the software directly from:
>
>          https://bitbucket.org/illustris/illustris_python
>         <https://bitbucket.org/illustris/illustris_python>
>
>         This command:
>
>          hg clone
>         https://bitbucket.org/illustris/stris_pythonillustris_python
>         <https://bitbucket.org/illustris/stris_pythonillustris_python>
>
>         should produce an "illustris_python" in the current directory,
>         and then her import command will find it.
>
>         However, there are other prerequisites. This pip command:
>
>          pip install h5py numpy
>
>         seems to resolve them. The OP will need to use Python 2 because
>         the module seems to rely on a relative import (for its "util.py"
>         file).
>
>         Cheers,
>         Cameron Simpson <cs at zip.com.au <mailto:cs at zip.com.au>>
>
>         _______________________________________________
>         Tutor maillist  -  Tutor at python.org <mailto:Tutor at python.org>
>         To unsubscribe or change subscription options:
>         https://mail.python.org/mailman/listinfo/tutor
>         <https://mail.python.org/mailman/listinfo/tutor>
>
>
>
>
>
>
> ---------- Forwarded message ----------
> From: Alan Gauld <alan.gauld at yahoo.co.uk>
> To: tutor <tutor at python.org>
> Cc:
> Bcc:
> Date: Sun, 23 Jul 2017 21:42:26 +0100
> Subject: [Tutor] Fwd: Re: Python Help
> Forwarding to list
>
>
>
> -------- Forwarded Message --------
>
> I did use the pip command and am attempting to add the files to my
> python path. I used
>  import sys
> sys.path.append("/Users/Jim/Documents/illustris_python")
>
> and that worked. I even checked to make sure the files were there
>
>
> import sys
> print (sys.path)
>
> ['', '/Users/Jim/anaconda/lib/python36.zip',
> '/Users/Jim/anaconda/lib/python3.6',
> '/Users/Jim/anaconda/lib/python3.6/lib-dynload',
> '/Users/Jim/anaconda/lib/python3.6/site-packages',
> '/Users/Jim/anaconda/lib/python3.6/site-packages/Sphinx-1.5.6-py3.6.egg',
> '/Users/Jim/anaconda/lib/python3.6/site-packages/aeosa',
> '/Users/Jim/anaconda/lib/python3.6/site-packages/
> setuptools-27.2.0-py3.6.egg',
> '/Users/Jim/anaconda/lib/python3.6/site-packages/IPython/extensions',
> '/Users/Jim/.ipython', 'Users/Jim/Documents/illustris_python']
>
> the file is clearly there but when i try to do import illustris_python
> as il it still can't find the module.
>
> I also figured that I need to manually export to python path so i tried:
> export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/
>   File "<ipython-input-14-30d153a77da5>", line 1
>     export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/
>                     ^
> SyntaxError: invalid syntax
>
> I got invalid syntax... using a mac os x
>
> I tried typing in terminal open .bash_profile and telling it to export
> the python path in there like some others recommended but in terminal it
> is giving me an error message for that... it must not be the right
> command for the shell.
>
> Winonah
>
> On Sat, Jul 22, 2017 at 9:34 PM, Cameron Simpson <cs at zip.com.au
> <mailto:cs at zip.com.au>> wrote:
>
>     On 23Jul2017 00:20, Alan Gauld <alan.gauld at yahoo.co.uk
>     <mailto:alan.gauld at yahoo.co.uk>> wrote:
>
>         On 22/07/17 19:14, Winonah Ojanen wrote:
>
>             using python with anaconda in jupiter notebook. However, I
>             am having
>
>
>         Usual caveat: The tutor list is targeted at the standard library
>         so any help for non standard library modules is best sought from
>         the library support fora. In this case that includes the SciPy
> forum
>         and any illustris one.
>
>
>     Though arguably the OP's problem is an import issue, not really
>     module specific.
>
>         That having been said, I'll take a guess...
>
>             $ mkdir Illustris-3
>             $ mkdir Illustris-3/groups_135
>
>         Are these folders in your PYTHONPATH? If not Python will not
>         find them.
>
>             import illustris_python as il
>             ------------------------------------------------------------
> ---------------
>             ModuleNotFoundError                       Traceback (most
>             recent call last)
>
>
>     The OP cded into the new dir; I'd normally expect things to be found
>     if the module was a local file/dir. However...
>
>             For some reason the computer is not recognizing this as a
>             file on my
>             computer. The CCA folks says this is a coding problem and
>             not an illustris
>             problem. any ideas to get me past this? I may also need help
>             getting
>             farther into the download process.
>
>
>     I just ran the OP's download command:
>
>      wget -nd -nc -nv -e robots=off -l 1 -r -A hdf5
>     --content-disposition --header="API-Key:
>     d522db2e1b33e36d3b365cc9ac1c2c5d"
>     "http://www.illustris-project.org/api/Illustris-3/files/
> groupcat-135/?format=api
>     <http://www.illustris-project.org/api/Illustris-3/files/
> groupcat-135/?format=api>"
>
>     This doesn't seem to download any Python code at all. It does get a
>     couple of HDF files, presumably with data to work with.
>
>     So the issue is initially that the module isn't present anywhere.
>     Looking at the instructions cited
>     <http://www.illustris-project.org/data/docs/scripts/
>     <http://www.illustris-project.org/data/docs/scripts/>>, they only
>     cover fetching som data and working; they presume the software is
>     already present. I don't immediately see actual software
>     installation instructions, and it is not presented in PyPI.
>
>     Most like the OP will have to install the software directly from:
>
>      https://bitbucket.org/illustris/illustris_python
>     <https://bitbucket.org/illustris/illustris_python>
>
>     This command:
>
>      hg clone
>     https://bitbucket.org/illustris/stris_pythonillustris_python
>     <https://bitbucket.org/illustris/stris_pythonillustris_python>
>
>     should produce an "illustris_python" in the current directory, and
>     then her import command will find it.
>
>     However, there are other prerequisites. This pip command:
>
>      pip install h5py numpy
>
>     seems to resolve them. The OP will need to use Python 2 because the
>     module seems to rely on a relative import (for its "util.py" file).
>
>     Cheers,
>     Cameron Simpson <cs at zip.com.au <mailto:cs at zip.com.au>>
>
>     _______________________________________________
>     Tutor maillist  -  Tutor at python.org <mailto:Tutor at python.org>
>     To unsubscribe or change subscription options:
>     https://mail.python.org/mailman/listinfo/tutor
>     <https://mail.python.org/mailman/listinfo/tutor>
>
>
>
>
>
> ---------- Forwarded message ----------
> From: Brandon Anderson <brandonanderson at me.com>
> To: tutor at python.org
> Cc:
> Bcc:
> Date: Sun, 23 Jul 2017 16:19:41 -0700
> Subject: [Tutor] Python3 Help
> Hello!
>
> 1.      I have Python3 installed on my 2017 MacBook Pro. I know that it is
> successfully installed because, when I enter ?Python3? into my terminal,
>         I get the following message:
>
>         Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06)
>         [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
>         Type "help", "copyright", "credits" or "license" for more
> information.
>
> 2.  I?m trying to locate the directory path to where Python3 is located on
> my system, but when I enter
>         the following command:
>         $ type -a python3
>
>         I get:
>         -bash: $: command not found
>
>         My understanding is that the command should have provided me with
> the path to Python3 is located on my system.
>
> 3.  How do I determine why I?m getting the ?error? command, instead of the
> directory location of Python3.
>     I need the location in order to setup my Text Editor to execute
> Python3 commands.
>
> Thank you in advance.
>
> Brandon Anderson
> (510) 468-0154
> brandonanderson at icloud.com
>
>
> ---------- Forwarded message ----------
> From: Michael C <mysecretrobotfactory at gmail.com>
> To: python tutor <tutor at python.org>
> Cc:
> Bcc:
> Date: Sun, 23 Jul 2017 13:24:49 -0700
> Subject: [Tutor] class newbie
> class mahschool:
>     def print():
>         print('Say something')
>
>
> a = mahschool()
>
> a.print()
>
>
>
> With this, I get this error:
>
> Traceback (most recent call last):
>   File "test.py", line 8, in <module>
>     a.print()
> TypeError: print() takes 0 positional arguments but 1 was given
>
>
> What did I do wrong?
>
> Thanks!
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>


_______________________________________________
Tutor maillist  -  Tutor at python.org
https://mail.python.org/mailman/listinfo/tutor

From alan.gauld at yahoo.co.uk  Wed Aug  2 16:07:00 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 2 Aug 2017 21:07:00 +0100
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
In-Reply-To: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
References: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
Message-ID: <oltbcu$1is$1@blaine.gmane.org>

On 02/08/17 20:01, C W wrote:

> I am a little confused about why Tuple can be sorted.
> 
> Suppose I have the following,
> 
>> aTuple = (9, 3, 7, 5)
>> sorted(aTuple)
> [3, 5, 7, 9]

sorted() returns a new object.
The original tuple has not been changed
 - print aTuple to confirm this.

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



From eryksun at gmail.com  Wed Aug  2 17:25:20 2017
From: eryksun at gmail.com (eryk sun)
Date: Wed, 2 Aug 2017 21:25:20 +0000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
Message-ID: <CACL+1asjfOR+jH2uQdQgjp5mAyaJ=1o1WjS=qRSJ9w1BNV3-gQ@mail.gmail.com>

On Wed, Aug 2, 2017 at 4:06 PM, Wolfgang Maier
<wolfgang.maier at biologie.uni-freiburg.de> wrote:
> On 08/02/2017 04:57 PM, Steven D'Aprano wrote:
>
>> I have a module with a main() function and an "if __name__ == ..."
>> guard. Under what circumstances is that not sufficient, and I would want
>> console_scripts?
>
> If you install things using pip/setuptools and have defined a
> console_scripts entry point for it, then the corresponding wrapper
> script will be installed in whatever is considered the scripts directory
> at install time on that machine. With a bit of luck the entry point will
> thus be executable directly without any end-user intervention (like
> adding folders to $PATH and chmodding files).
> Personally, I always found it straightforward to write the wrapper
> script myself, then define this as a 'scripts' file in the package
> layout of my setup.py, but people's MMV.

For Windows, using frozen executables is preferred because
CreateProcess doesn't support shebangs. setuptools freezes entry-point
scripts with one of the following stub executables: console_scripts
(cli-32.exe, cli-64.exe) and gui_scripts (gui-32.exe, gui-64.exe).
Actually, it's better to create and install a wheel package, for which
pip uses the newer stubs from distlib: console_scripts (t32.exe,
t64.exe) and gui_scripts (w32.exe, w64.exe). Most Python 3
installations on Windows have at least two entry-point scripts:
pip.exe and easy_install.exe.

From alan.gauld at yahoo.co.uk  Wed Aug  2 19:00:25 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 3 Aug 2017 00:00:25 +0100
Subject: [Tutor] Loop problem (was: Re: Tutor Digest, Vol 161, Issue 42)
In-Reply-To: <CAKE=nh7ihgz_2KLjbJy-yJvy4=cdExQ8E5ymGrJcJurN_OsUFw@mail.gmail.com>
References: <CAKE=nh7ihgz_2KLjbJy-yJvy4=cdExQ8E5ymGrJcJurN_OsUFw@mail.gmail.com>
Message-ID: <oltli2$hv4$1@blaine.gmane.org>

On 02/08/17 20:53, Borisco Bizaro wrote:
> I try this using loop but could not stop by pressing a key and could not
> give total price please help me

It would help if you showed us the code you wrote with the loop.
Its difficult to guess what you did wrong when we can't see it.

> print"\n welcome to progrom that print total price\n"
> a=int(input("enter the first price: "))
> b=int(input ("enter another price: "))
> c=int(input ("enter another price: "))
> d=int(input ("enter another price: "))
> f=int(input ("enter another price: "))
> g=int(input ("enter another price: "))
> h=int(input ("enter another price: "))
> total=a+b+c+d+f+g+h

Here is a hint...
You could collect the prices in a list then use sum()
to get the total. Then your loop only needs to read a
value and append() it to the list. break out of the loop
if the user enters 0, or -1, or whatever you want to stop it.

> print"\n totol",a+b+c+d+f+g+h
> print("\n\n press the o key to exit ")

Notice one print uses parentheses, the other doesn't.
Which version of Python are you using? Its better if
you stick to one form or the other as appropriate
to your Python version.

> This is what I did but could not be able to used while loop
> On Jul 30, 2017 23:44, <tutor-request at python.org> wrote:
> 
> Send Tutor mailing list submissions to
>         tutor at python.org
> 

Please delete the digest material (it wastes bandwidth
and costs some folks money) and change the subject line
to something hewlpful, as suggested here...

> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
> 

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



From alan.gauld at alan-g.me.uk  Wed Aug  2 19:09:09 2017
From: alan.gauld at alan-g.me.uk (Alan Gauld)
Date: Thu, 3 Aug 2017 00:09:09 +0100
Subject: [Tutor] The results of your email commands
In-Reply-To: <CAKE=nh6y0s+z-z77m4RRRHM=Fp56MKnpORQEP0J3xKbFbQDTWA@mail.gmail.com>
References: <ojjkrkmgpr3p7e7qwuafi0yf.1487097968660@email.android.com>
 <CAKE=nh6z+SeQm687quc026H0E-hbpqftuX1Va+VquwNcWeVRng@mail.gmail.com>
 <d63b53a9-c12e-8a0a-76eb-2a92389116b7@yahoo.co.uk>
 <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk>
 <CAKE=nh6y0s+z-z77m4RRRHM=Fp56MKnpORQEP0J3xKbFbQDTWA@mail.gmail.com>
Message-ID: <f88f7dcb-39c8-2662-ce0c-c0a861ceab3a@alan-g.me.uk>

I'[ve CCd the list, please use ReplyAll when responding to the list.


On 02/08/17 22:13, Borisco Bizaro wrote:
>     Hi,am try to write a code that take input from user continuently
>     until key press it stop and give total amount user  enter.

>     while True:
>       input ("enter another price :")
>     print"\n\n press 0 key to stop"

The last line should probably be before the loop.

You need to store the value somewhere, probably in a list
of prices.

Also you need to convert the input value to a number, probably
a float in this case(although for a real system you'd probably
use a Decimal or a multiplied integer for money.)

You also need to check the value before you store it to see
if its the last value (ie "0"). Something like

value = input(....)
if value == "0": break
try: prices.append(float(value))
except ValueError: print "you need a number"


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


From tmrsg11 at gmail.com  Wed Aug  2 21:32:43 2017
From: tmrsg11 at gmail.com (C W)
Date: Wed, 2 Aug 2017 21:32:43 -0400
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
In-Reply-To: <oltbcu$1is$1@blaine.gmane.org>
References: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
 <oltbcu$1is$1@blaine.gmane.org>
Message-ID: <CAE2FW2mspyHLovh3FwMUWCO5JBSdsJDGrDU9_ZmSSBJX3NWafA@mail.gmail.com>

As pointed out by someone else, ?sorted
sorted(iterable, key=None, reverse=False)

It seems like the only requirement is iterable. I guess tuple is iterable,
so, it doesn't break the assumption that tuple is immutable.

That's what I see, am I right in that?

Thanks!

On Wed, Aug 2, 2017 at 4:07 PM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 02/08/17 20:01, C W wrote:
>
> > I am a little confused about why Tuple can be sorted.
> >
> > Suppose I have the following,
> >
> >> aTuple = (9, 3, 7, 5)
> >> sorted(aTuple)
> > [3, 5, 7, 9]
>
> sorted() returns a new object.
> The original tuple has not been changed
>  - print aTuple to confirm this.
>
> HTH
> --
> 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
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From arj.python at gmail.com  Thu Aug  3 06:05:05 2017
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Thu, 3 Aug 2017 14:05:05 +0400
Subject: [Tutor] The results of your email commands
In-Reply-To: <f88f7dcb-39c8-2662-ce0c-c0a861ceab3a@alan-g.me.uk>
References: <ojjkrkmgpr3p7e7qwuafi0yf.1487097968660@email.android.com>
 <CAKE=nh6z+SeQm687quc026H0E-hbpqftuX1Va+VquwNcWeVRng@mail.gmail.com>
 <d63b53a9-c12e-8a0a-76eb-2a92389116b7@yahoo.co.uk>
 <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk>
 <CAKE=nh6y0s+z-z77m4RRRHM=Fp56MKnpORQEP0J3xKbFbQDTWA@mail.gmail.com>
 <f88f7dcb-39c8-2662-ce0c-c0a861ceab3a@alan-g.me.uk>
Message-ID: <CADrxXXnDunLBBGyQ9JhY7h6fOHemYTGWLKbWjJ9pzS2D-ZROXA@mail.gmail.com>

me i cooked up :

[warning : see code above better but i did it a bit differently]

x = True
sum = 0

while (x==True):
    a = input("input:")
    if a =="exit":
        x=False
    try:
        sum += float(a)
    except:
        pass

print("sum :",sum)

On Thu, Aug 3, 2017 at 3:09 AM, Alan Gauld <alan.gauld at alan-g.me.uk> wrote:

> I'[ve CCd the list, please use ReplyAll when responding to the list.
>
>
> On 02/08/17 22:13, Borisco Bizaro wrote:
> >     Hi,am try to write a code that take input from user continuently
> >     until key press it stop and give total amount user  enter.
>
> >     while True:
> >       input ("enter another price :")
> >     print"\n\n press 0 key to stop"
>
> The last line should probably be before the loop.
>
> You need to store the value somewhere, probably in a list
> of prices.
>
> Also you need to convert the input value to a number, probably
> a float in this case(although for a real system you'd probably
> use a Decimal or a multiplied integer for money.)
>
> You also need to check the value before you store it to see
> if its the last value (ie "0"). Something like
>
> value = input(....)
> if value == "0": break
> try: prices.append(float(value))
> except ValueError: print "you need a number"
>
>
> --
> 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
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From bandagunda at hotmail.com  Thu Aug  3 07:22:20 2017
From: bandagunda at hotmail.com (banda gunda)
Date: Thu, 3 Aug 2017 11:22:20 +0000
Subject: [Tutor] file move with wait period
Message-ID: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>

Dear tutors,

I am interested to move a set of files, periodically, from source_folder to dest_folder.
source_folder receives processed files from a ?decompressing program?.  The files are deposited from the ?decompressing program? at periodic random intervals.  Furthermore some of the files dropped in the source_folder are large, of typical size 800MB.  These files take time before it is completely deposited in the source_folder.

I could use shutil.move (source_folder, dest_folder).  But then how?

The frequency of moving files from source_folder to dest_folder is flexible.  It could be once in 15 minutes (or even lengthier).
Challenge for me:  How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder?
Thanks in advance for your comments/guidance.

Best,
Kumar.
+


From guettliml at thomas-guettler.de  Thu Aug  3 03:52:26 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Thu, 3 Aug 2017 09:52:26 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
Message-ID: <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>



Am 02.08.2017 um 18:06 schrieb Wolfgang Maier:
> On 08/02/2017 04:57 PM, Steven D'Aprano wrote:
>> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote:
>>> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
>>>
>>>> Maybe I am doing something wrong.  I was proud because I did use
>>>> ?console_scripts? entry points.
>>>
>>> Did someone lead you to believe it was wrong? Setuptools console_scripts
>>> entry points are a good tool.
>>>
>>> My point was that it is an *advanced* tool, difficult to use and also
>>> difficult to explain because the concepts are advanced.
>>
>> Can you explain the use-case for when somebody might want to use
>> console_scripts entry points?
>>
>> I have a module with a main() function and an "if __name__ == ..."
>> guard. Under what circumstances is that not sufficient, and I would want
>> console_scripts?
>>
> 
> If you install things using pip/setuptools and have defined a
> console_scripts entry point for it, then the corresponding wrapper
> script will be installed in whatever is considered the scripts directory
> at install time on that machine. With a bit of luck the entry point will
> thus be executable directly without any end-user intervention (like
> adding folders to $PATH and chmodding files).
> Personally, I always found it straightforward to write the wrapper
> script myself, then define this as a 'scripts' file in the package
> layout of my setup.py, but people's MMV.


I was not aware of "scripts" in setup.py. But I found docs:

   http://python-packaging.readthedocs.io/en/latest/command-line-scripts.html

Why are there two ways: "script" vs "console_scripts entry-point"?

Regards,
   Thomas


-- 
Thomas Guettler http://www.thomas-guettler.de/

From alan.gauld at yahoo.co.uk  Thu Aug  3 12:21:24 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 3 Aug 2017 17:21:24 +0100
Subject: [Tutor] The results of your email commands
In-Reply-To: <CADrxXXnDunLBBGyQ9JhY7h6fOHemYTGWLKbWjJ9pzS2D-ZROXA@mail.gmail.com>
References: <ojjkrkmgpr3p7e7qwuafi0yf.1487097968660@email.android.com>
 <CAKE=nh6z+SeQm687quc026H0E-hbpqftuX1Va+VquwNcWeVRng@mail.gmail.com>
 <d63b53a9-c12e-8a0a-76eb-2a92389116b7@yahoo.co.uk>
 <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk>
 <CAKE=nh6y0s+z-z77m4RRRHM=Fp56MKnpORQEP0J3xKbFbQDTWA@mail.gmail.com>
 <f88f7dcb-39c8-2662-ce0c-c0a861ceab3a@alan-g.me.uk>
 <CADrxXXnDunLBBGyQ9JhY7h6fOHemYTGWLKbWjJ9pzS2D-ZROXA@mail.gmail.com>
Message-ID: <olvii2$ssg$1@blaine.gmane.org>

On 03/08/17 11:05, Abdur-Rahmaan Janhangeer wrote:
> me i cooked up :...

Yes that works too, especially if you don;t need access
to the individual prices later.

There are a couple of things to make it more Pythonic...

> x = True
> sum = 0
> 
> while (x==True):
>     a = input("input:")
>     if a =="exit":
>         x=False

You could replace that with

sum = 0
while True:
     a = input("input:")
     if a =="exit":
         break    # exit the loop

and

>     try:
>         sum += float(a)
>     except:
>         pass

That's a risky strategy because if there is
any error other than the one you anticipate
then you will never know about it and
ignore it. You should always try to specify
the error(s) if possible:

try:
   sum += float(a)
except ValueError, TypeError:
   pass

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



From kwpolska at gmail.com  Thu Aug  3 12:22:58 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Thu, 3 Aug 2017 18:22:58 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
Message-ID: <CAMw+j7LNxVa289ZRZihjPoWK5EizTGs_YYN1UwARX5cx99xBjQ@mail.gmail.com>

On 3 August 2017 at 09:52, Thomas G?ttler <guettliml at thomas-guettler.de> wrote:
>
>
> Am 02.08.2017 um 18:06 schrieb Wolfgang Maier:
>>
>> On 08/02/2017 04:57 PM, Steven D'Aprano wrote:
>>>
>>> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote:
>>>>
>>>> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
>>>>
>>>>> Maybe I am doing something wrong.  I was proud because I did use
>>>>> ?console_scripts? entry points.
>>>>
>>>>
>>>> Did someone lead you to believe it was wrong? Setuptools console_scripts
>>>> entry points are a good tool.
>>>>
>>>> My point was that it is an *advanced* tool, difficult to use and also
>>>> difficult to explain because the concepts are advanced.
>>>
>>>
>>> Can you explain the use-case for when somebody might want to use
>>> console_scripts entry points?
>>>
>>> I have a module with a main() function and an "if __name__ == ..."
>>> guard. Under what circumstances is that not sufficient, and I would want
>>> console_scripts?
>>>
>>
>> If you install things using pip/setuptools and have defined a
>> console_scripts entry point for it, then the corresponding wrapper
>> script will be installed in whatever is considered the scripts directory
>> at install time on that machine. With a bit of luck the entry point will
>> thus be executable directly without any end-user intervention (like
>> adding folders to $PATH and chmodding files).
>> Personally, I always found it straightforward to write the wrapper
>> script myself, then define this as a 'scripts' file in the package
>> layout of my setup.py, but people's MMV.
>
>
>
> I was not aware of "scripts" in setup.py. But I found docs:
>
>   http://python-packaging.readthedocs.io/en/latest/command-line-scripts.html
>
> Why are there two ways: "script" vs "console_scripts entry-point"?

Simple: `scripts` are legacy. `entry_points` are the new thing.
There?s also a third approach: gui_scripts entry_points, which work
the same way on Linux/*nix, but on Windows, it means that running your
script by opening the created .exe files does not show a console
window. Note that stdout/stderr do not work in that mode under
Windows, which can lead to spurious application crashes.  (GUI-only
processes cannot use stdout/stderr because they don?t have a console
attached)

I?ll take the liberty to link my (better) blog post about this:
https://chriswarrick.com/blog/2014/09/15/python-apps-the-right-way-entry_points-and-scripts/

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From mats at wichmann.us  Thu Aug  3 12:54:34 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 3 Aug 2017 10:54:34 -0600
Subject: [Tutor] The results of your email commands
In-Reply-To: <olvii2$ssg$1@blaine.gmane.org>
References: <ojjkrkmgpr3p7e7qwuafi0yf.1487097968660@email.android.com>
 <CAKE=nh6z+SeQm687quc026H0E-hbpqftuX1Va+VquwNcWeVRng@mail.gmail.com>
 <d63b53a9-c12e-8a0a-76eb-2a92389116b7@yahoo.co.uk>
 <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk>
 <CAKE=nh6y0s+z-z77m4RRRHM=Fp56MKnpORQEP0J3xKbFbQDTWA@mail.gmail.com>
 <f88f7dcb-39c8-2662-ce0c-c0a861ceab3a@alan-g.me.uk>
 <CADrxXXnDunLBBGyQ9JhY7h6fOHemYTGWLKbWjJ9pzS2D-ZROXA@mail.gmail.com>
 <olvii2$ssg$1@blaine.gmane.org>
Message-ID: <06a282a6-caab-2d6d-d878-505063d93eb8@wichmann.us>

On 08/03/2017 10:21 AM, Alan Gauld via Tutor wrote:
> On 03/08/17 11:05, Abdur-Rahmaan Janhangeer wrote:
>> me i cooked up :...
> 
> Yes that works too, especially if you don;t need access
> to the individual prices later.
> 
> There are a couple of things to make it more Pythonic...
> 
>> x = True
>> sum = 0
>>
>> while (x==True):
>>     a = input("input:")
>>     if a =="exit":
>>         x=False
> 
> You could replace that with
> 
> sum = 0
> while True:
>      a = input("input:")
>      if a =="exit":
>          break    # exit the loop

I'd like to add a thought here... checking for a precise string as a
quit marker is fine, but it might be a little friendlier to accept
spelling variants (as long as none of them could be confused with valid
values... true in this case as you want numbers)... and also to let your
user know what you're expecting!

thus:

    a = input("enter number ('exit' when done):)
    if a in ('x', 'exit', 'Exit'):

> 
> and
> 
>>     try:
>>         sum += float(a)
>>     except:
>>         pass
> 
> That's a risky strategy because if there is
> any error other than the one you anticipate
> then you will never know about it and
> ignore it. You should always try to specify
> the error(s) if possible:
> 
> try:
>    sum += float(a)
> except ValueError, TypeError:
>    pass
> 


From steve at pearwood.info  Thu Aug  3 20:46:35 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 4 Aug 2017 10:46:35 +1000
Subject: [Tutor] basic decorator question
In-Reply-To: <CANDiX9J0SyO4+_4UwNFBjqS1a-8O4CTj6brV9VF0CchQf255WA@mail.gmail.com>
References: <CAP16ngq88xZUk9JUVV-9ouCSG-Xu6ioMwUZa-BdPgxpvOXY1jg@mail.gmail.com>
 <20170724160129.GP3149@ando.pearwood.info>
 <CANDiX9J0SyO4+_4UwNFBjqS1a-8O4CTj6brV9VF0CchQf255WA@mail.gmail.com>
Message-ID: <20170804004634.GR3149@ando.pearwood.info>

Sorry for the delay in responding to this thread!

On Wed, Jul 26, 2017 at 09:22:59PM -0500, boB Stepp wrote:

> I am having a recurring problem with Python:  I can work out the
> mechanics of how various Python constructs work, such as decorators,
> but then I find myself scratching my head as to why would I want to
> use them.  The idea of replacing a function with its decorated version
> sounds cool, but what types of problems would I want to use this
> approach on?

Any time you have a series of functions (or classes) which include the 
same subsection of code, repeated (often word-for-word!), a decorator is 
a possible alternative.

Here's a simple example. You have a bunch of functions which all follow 
the same pattern when called:

- print the function name
- print their arguments
- do some work
- print their return result
- return it

Only the "work" differs. So we could write:


def func1(a, b, c):
    print("func1")
    print(a, b, c)
    result = a + b + c
    print("result", result)
    return result

def func2(a, b, c):
    print("func1")  # Oops, copy-and-paste error!
    print(a, b, c)
    result = a - b - c
    print("result", result)
    return result


and so on, but if you have a dozen such functions, that's pretty 
tedious, and the chances of copy-and-paste errors approaches 
certainty. A decorator comes to the rescue!


def decorate(func):
    @functools.wraps(func)
    def inner(a, b, c):
        print(func.__name__)
        print(a, b, c)
        result = func(a, b, c)
        print(result)
        return result
    return inner

@decorate
def func1(a, b, c):
    return a+b+c
       
@decorate
def func2(a, b, c):
    return a-b-c
        

This ensures that all such functions are guaranteed to have the correct 
wrapper code. If you decide to add printing of the date, or change 
printing to logging to a file, you only need to change it in one place, 
not a dozen.


Another use for decorators is to transform the functions in some way. 
That's especially useful for methods, where we have three different 
kinds of methods:

- regular instance methods, which need no transformation because
  they are the default;

- class methods;

- static methods.

Plus you can create your own, if needed. (A fairly advanced topic, but 
less mind-blowing than metaclasses.)

They are all written the same way, with the difference being that class 
and static methods are decorated with the built-in

- classmethod
- staticmethod

decorators, which handle transforming the function objects into 
classmethod or staticmethod descriptors. Don't worry if you don't know 
the technical details of what descriptors are or how they work. The 
point is you don't need to! You just need to call the decorator, and it 
does all the work.


class X(object):
    @classmethod
    def thingy(cls, arg):
        ...


Another example is to register a function with something else. If you 
have code where you create functions, then register them, you can 
simplify the process or at least move the registration to the top of the 
function where it is more obvious with a decorator:


def register(func):
    MyRegistry.register(func)
    return func

@register
def spam():
    ...


If you need to change the registration details, you change it in one 
place. This is an example that shows that decorators don't need to 
transform their input. In this case, we return the function unchanged.


A more complex example of this is singledispatch:

https://docs.python.org/3/library/functools.html#functools.singledispatch


Memoization (adding a cache) to a function is another good example. 
Instead of re-creating the cache logic in every single function, you 
write it once, as a decorator, and then just call the decorator.

https://docs.python.org/3/library/functools.html#functools.lru_cache



> One thing that bothers me, is that once I decorate the function, I no
> longer have access to the original, un-decorated function.

In the most general case, that is true: the decorator can do anything, 
including deleting the original and replacing it with a function that 
always returns "?Qu??" no matter the arguments.

Most of the time, this is not a problem. The function is *incomplete* 
until it has been decorated, so you often don't care about the original. 
Do you find yourself worrying that you don't have access to the middle 
one third of your existing functions, without the start and the end? 
Probably not. All that's happened here is that you've systematically 
moved the common bits of your functions into a decorator.

But for those cases where you might care, and since Python 3.2, if you 
use the functools.wraps() helper function (itself a decorator!) to 
create your decorators, it will automatically create a __wrapped__ 
attribute that holds the original, unwrapped function.


> But on the
> other hand, if I had a decorator which I wanted to apply to multiple
> functions, then I would be DRY-er by taking this approach -- I would
> need only one decorator function and could then use it decorate as
> many other functions as it made sense to do so.

Precisely.



-- 
Steve

From ben+python at benfinney.id.au  Thu Aug  3 20:50:31 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Fri, 04 Aug 2017 10:50:31 +1000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info>
 <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
Message-ID: <85a83gp354.fsf@benfinney.id.au>

Thomas G?ttler <guettliml at thomas-guettler.de> writes:

> Why are there two ways: "script" vs "console_scripts entry-point"?

Because Distutils implements only ?scripts?, and that's not capable
enough for what people need so Setuptools implements entry points.

In other words: One of them is in the standard library and does
something; the other is third-party and can do more.

That answers why there are two. But maybe you wanted to ask some
underlying question?

-- 
 \           ?It ain't so much the things we don't know that get us in |
  `\    trouble. It's the things we know that ain't so.? ?Artemus Ward |
_o__)                                     (1834?1867), U.S. journalist |
Ben Finney


From 1019shaun at gmail.com  Thu Aug  3 16:27:12 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Thu, 3 Aug 2017 13:27:12 -0700
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0Jesjg9KXMZvqxwThk74-s26ehQZzrCYYbQa5Xm8=NG-fM6g@mail.gmail.com>
References: <CAG0Jesi1FSzK6nadqvEcHgiL7bmDbcFWGhyKApy42orhgjofVg@mail.gmail.com>
 <CAG0JesjORg7aBLf_7GD1U2hzRU=meEC6n+Bv+DsWUxWcdOG61g@mail.gmail.com>
 <CAG0JeshsM+LFF_tVo41z1+H=MGJimM2X4pL-a=-UG7Ax_ic+RQ@mail.gmail.com>
 <CAG0Jesg5_Je-ohcTLr4enU2iS+5U-HA-ZgD6_JuDKxw=XRdRAA@mail.gmail.com>
 <CAG0JeshbBfN7Yg=DFTvpwdrVwSW56hOUQJdzG-=9HWhy_oqNVg@mail.gmail.com>
 <CAG0JesinzTEAQM8x-rdhoeO88k_QwmJuV2-qPB-ngjXOg-3=Xw@mail.gmail.com>
 <CAG0JesgyHpyi1Sw7+xi8Bx4J_TCWSJx6-P5CTo=E+iK+2doh3g@mail.gmail.com>
 <CAG0JesgZzLFh64MhiEHYcb-ywjmg7_uqTwziSGW4CriokOXufQ@mail.gmail.com>
 <CAG0JeshPoqP_68oZE+W8Lx6NyiNcwu+iARDbsL+S9cW_rDCQaA@mail.gmail.com>
 <CAG0Jesj1R_nit9tNivk=V_SEwhAxdmq5RorEVBySV_Y3VqTMzw@mail.gmail.com>
 <CAG0JesjKeWXn28-vsThuVxS8cSf=qGZSsDr16Y6FgASrFbdfhw@mail.gmail.com>
 <CAG0Jesj6C15DKBebTvwuiD3gtUpxWvwmahGf1ki+EWMNbgAFFw@mail.gmail.com>
 <CAG0Jesj5u7DPPS0_PNQ_NdrPP+0VYDmRuHz_R-RisdVPrnAp5A@mail.gmail.com>
 <CAG0JesjJAG+ANSNQRR_fPew3JAvVPmt=NRZVKkO8_FRWk5B0Tg@mail.gmail.com>
 <CAG0JesjYCeVwa+noMcLVDYYMZUp1OzWxycqibFDudpNttape6A@mail.gmail.com>
 <CAG0Jesjg9KXMZvqxwThk74-s26ehQZzrCYYbQa5Xm8=NG-fM6g@mail.gmail.com>
Message-ID: <CAG0JeshBZo=064058Pqs=UF+uWGhnWUNZqxY4yyRuJ7xy3DFGw@mail.gmail.com>

hi ! i am newbie to coding love it but need help with problems which i
searched but poor results this is the error: typeError unorderable types:
int()<str()
the code in short, number=random.randint(1,20)
guess=input()
guess=int(guess)
but when reach the line that says
if guess<number:

i get the error ! help

From cs at cskk.id.au  Thu Aug  3 23:18:58 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Fri, 4 Aug 2017 13:18:58 +1000
Subject: [Tutor] file move with wait period
In-Reply-To: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>
References: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <20170804031858.GA23376@cskk.homeip.net>

On 03Aug2017 11:22, banda gunda <bandagunda at hotmail.com> wrote:
>Dear tutors,
>
>I am interested to move a set of files, periodically, from source_folder to dest_folder.
>source_folder receives processed files from a ?decompressing program?.  The files are deposited from the ?decompressing program? at periodic random intervals.  Furthermore some of the files dropped in the source_folder are large, of typical size 800MB.  These files take time before it is completely deposited in the source_folder.
>
>I could use shutil.move (source_folder, dest_folder).  But then how?

You'd normally use shutil.move(source_file, dest_file) i.e. move individual 
files. Or os.rename, but that requires that the source and dest are the same 
filesystem.

>The frequency of moving files from source_folder to dest_folder is flexible.  It could be once in 15 minutes (or even lengthier).
>Challenge for me:  How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder?
>Thanks in advance for your comments/guidance.

That is the tricky thing; this shows up a lot, also with FTP upload locations 
and so forth.

The problem, as you state, is knowing when the file is complete. There are 2 
basic approaches: do not put a fil into the transfer directory before it is 
complete, or to monitor the files for changes. On the premise that the file 
will be being actively written until it is complete you could keep a list if 
the files in the directory. For each name, record the file's size and 
modification time. Wait for that to be unchanged "long enough"; you might then 
decide it is ready to move.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From robertvstepp at gmail.com  Thu Aug  3 23:47:19 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 3 Aug 2017 22:47:19 -0500
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0JeshBZo=064058Pqs=UF+uWGhnWUNZqxY4yyRuJ7xy3DFGw@mail.gmail.com>
References: <CAG0Jesi1FSzK6nadqvEcHgiL7bmDbcFWGhyKApy42orhgjofVg@mail.gmail.com>
 <CAG0JesjORg7aBLf_7GD1U2hzRU=meEC6n+Bv+DsWUxWcdOG61g@mail.gmail.com>
 <CAG0JeshsM+LFF_tVo41z1+H=MGJimM2X4pL-a=-UG7Ax_ic+RQ@mail.gmail.com>
 <CAG0Jesg5_Je-ohcTLr4enU2iS+5U-HA-ZgD6_JuDKxw=XRdRAA@mail.gmail.com>
 <CAG0JeshbBfN7Yg=DFTvpwdrVwSW56hOUQJdzG-=9HWhy_oqNVg@mail.gmail.com>
 <CAG0JesinzTEAQM8x-rdhoeO88k_QwmJuV2-qPB-ngjXOg-3=Xw@mail.gmail.com>
 <CAG0JesgyHpyi1Sw7+xi8Bx4J_TCWSJx6-P5CTo=E+iK+2doh3g@mail.gmail.com>
 <CAG0JesgZzLFh64MhiEHYcb-ywjmg7_uqTwziSGW4CriokOXufQ@mail.gmail.com>
 <CAG0JeshPoqP_68oZE+W8Lx6NyiNcwu+iARDbsL+S9cW_rDCQaA@mail.gmail.com>
 <CAG0Jesj1R_nit9tNivk=V_SEwhAxdmq5RorEVBySV_Y3VqTMzw@mail.gmail.com>
 <CAG0JesjKeWXn28-vsThuVxS8cSf=qGZSsDr16Y6FgASrFbdfhw@mail.gmail.com>
 <CAG0Jesj6C15DKBebTvwuiD3gtUpxWvwmahGf1ki+EWMNbgAFFw@mail.gmail.com>
 <CAG0Jesj5u7DPPS0_PNQ_NdrPP+0VYDmRuHz_R-RisdVPrnAp5A@mail.gmail.com>
 <CAG0JesjJAG+ANSNQRR_fPew3JAvVPmt=NRZVKkO8_FRWk5B0Tg@mail.gmail.com>
 <CAG0JesjYCeVwa+noMcLVDYYMZUp1OzWxycqibFDudpNttape6A@mail.gmail.com>
 <CAG0Jesjg9KXMZvqxwThk74-s26ehQZzrCYYbQa5Xm8=NG-fM6g@mail.gmail.com>
 <CAG0JeshBZo=064058Pqs=UF+uWGhnWUNZqxY4yyRuJ7xy3DFGw@mail.gmail.com>
Message-ID: <CANDiX9KuW9T+gxZ=yhEFFYX7Fp1-M7T3=MbKTLn=4OCQWHF7vw@mail.gmail.com>

Greetings Howard!

On Thu, Aug 3, 2017 at 3:27 PM, Howard Lawrence <1019shaun at gmail.com> wrote:
> hi ! i am newbie to coding love it but need help with problems which i
> searched but poor results this is the error: typeError unorderable types:
> int()<str()
> the code in short, number=random.randint(1,20)
> guess=input()
> guess=int(guess)
> but when reach the line that says
> if guess<number:
>
> i get the error ! help

With the code snippets you've shown in the order you have shown them,
I would not expect you to get this error as it appears that you have
converted the string values from your input statements into integers.
But I suspect that you have not shown the part of the code that is
generating the error.

When posting to this list (Or any other coding list for that matter.)
you should always *copy and paste* into your plain text email the
actual code giving the error.  And then *copy and paste* the FULL
error traceback you receive.  And it does not hurt to give the python
version you are using and the operating system on your machine, too.

At this point I can only guess at things.  Since apparently this is a
number guessing game, you probably have a while loop. Did you use your
variable "guess" in the while statement's condition *before*
converting it to an integer?

Somewhere in your code you are checking that an integer is less than a
string, which is not doable.  The error traceback should tell you what
line number to start looking.

If this does not help then you need to resend your message with your
full code and full traceback unless someone else has better oracle
abilities... ~(:>))



-- 
boB

From eryksun at gmail.com  Fri Aug  4 00:12:22 2017
From: eryksun at gmail.com (eryk sun)
Date: Fri, 4 Aug 2017 04:12:22 +0000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <CAMw+j7LNxVa289ZRZihjPoWK5EizTGs_YYN1UwARX5cx99xBjQ@mail.gmail.com>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <CAMw+j7LNxVa289ZRZihjPoWK5EizTGs_YYN1UwARX5cx99xBjQ@mail.gmail.com>
Message-ID: <CACL+1as6PShsk9N5HyTBvKoTx+f4xG-TK1p_ge7VoLQd-n1GHQ@mail.gmail.com>

On Thu, Aug 3, 2017 at 4:22 PM, Chris Warrick <kwpolska at gmail.com> wrote:
>
> Simple: `scripts` are legacy. `entry_points` are the new thing.
> There?s also a third approach: gui_scripts entry_points, which work
> the same way on Linux/*nix, but on Windows, it means that running your
> script by opening the created .exe files does not show a console
> window. Note that stdout/stderr do not work in that mode under
> Windows, which can lead to spurious application crashes.  (GUI-only
> processes cannot use stdout/stderr because they don?t have a console
> attached)

A Windows GUI executable doesn't automatically inherit or create a
console for standard I/O. (It has to manually call AttachConsole or
AllocConsole.) But it does automatically inherit the standard handle
values from the parent process (just the integer values, not the
handles themselves). If these handles are inheritable and the child is
created with handle inheritance, then standard I/O will work. For
example:

    C:\Temp>echo spam | pythonw -c print(input()) >out.txt 2>&1
    C:\Temp>type out.txt
    spam

In the above example pythonw.exe is a GUI executable. The example
reads "spam" from stdin and prints it to stdout, which is redirected
to a file named "out.txt". For those who don't know, `>out.txt` is
shell syntax to redirect stdout to "out.txt", and `2>&1` redirects
stderr (2) to stdout (1).

From mats at wichmann.us  Fri Aug  4 00:23:28 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 3 Aug 2017 22:23:28 -0600
Subject: [Tutor] file move with wait period
In-Reply-To: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>
References: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <15e777d7-a32f-cc3a-3012-625a29225434@wichmann.us>

On 08/03/2017 05:22 AM, banda gunda wrote:
> Dear tutors,
> 
> I am interested to move a set of files, periodically, from source_folder to dest_folder.
> source_folder receives processed files from a ?decompressing program?.  The files are deposited from the ?decompressing program? at periodic random intervals.  Furthermore some of the files dropped in the source_folder are large, of typical size 800MB.  These files take time before it is completely deposited in the source_folder.
> 
> I could use shutil.move (source_folder, dest_folder).  But then how?
> 
> The frequency of moving files from source_folder to dest_folder is flexible.  It could be once in 15 minutes (or even lengthier).
> Challenge for me:  How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder?

Well, we cannot answer that question with the information you have given.

"How can you know" is actually the key question to explore. You need to
answer it before you worry about any Pythonic implementation details of
solving your problem.

- is the decompressor initiated by your program?  In that case there
will be techniques to maintain communication with it to find out when it
is done (perhaps as simple as waiting for it to quit-with-success).
- if it launches completely independently, how do you find out that it
has deposited files? Do you intend to just can periodically? Or is there
a way that the system causing the files to be generated can trigger
something that your program could be asked to be notified about when a
file is available?
- is it possible to convice the compressor to give files a certain
suffix or other recognizable pattern, but only when they are complete?
(downloader systems often work like this... while they're writing the
file, it has some temporary name, then when it finishes it is renamed to
the intended target name).

and so on.

From cs at cskk.id.au  Thu Aug  3 21:57:07 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Fri, 4 Aug 2017 11:57:07 +1000
Subject: [Tutor] if __name__=='main' vs entry points: What to teach new
 comers?
In-Reply-To: <20170802145741.GN3149@ando.pearwood.info>
References: <20170802145741.GN3149@ando.pearwood.info>
Message-ID: <20170804015707.GA62002@cskk.homeip.net>

On 03Aug2017 00:57, Steven D'Aprano <steve at pearwood.info> wrote:
>Can you explain the use-case for when somebody might want to use
>console_scripts entry points?
>
>I have a module with a main() function and an "if __name__ == ..."
>guard. Under what circumstances is that not sufficient, and I would want
>console_scripts?

I have a bunch of "one liner" scripts in my personal "bin" directory like this 
one:

    #!/bin/sh
    #
    # Run the named port forwards indefinitely.
    #       - Cameron Simpson <cs at zip.com.au> 08jul2008
    #
    # Convert to Python module cs.app.portfwd. - cameron, may2017
    #
    exec python3 -m cs.app.portfwd ${1+"$@"}

It relies on the __main__ thing in the cs.app.portfwd module, and many of my 
modules have a main, as I gather do yours.

For a lot of modules that main just runs the selftests, but for some the main 
is a perfectly reasonable command, such as "portfwd" above. So an install 
implies having an invocation script. By hand, I can do the above script.

But if I'm distributing the module via PyPI, how do I install the invocable 
script in the $PATH eg the virtualenv's bin? The installer knows where the 
"bin" is, but on windows the script install is not the same as on UNIX.

So the console_scripts dict provides a mapping from script names to 
module.function callables, and setup installs the right thing. It also 
separates the script name from the module/function names.

Also, modules are groups by function topic. A module may have more than one 
function within it which are suitable command line implementations. The 
console_scripts mapping lets one bind multiple script to suitable entry points.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From cs at cskk.id.au  Thu Aug  3 22:03:16 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Fri, 4 Aug 2017 12:03:16 +1000
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0JeshBZo=064058Pqs=UF+uWGhnWUNZqxY4yyRuJ7xy3DFGw@mail.gmail.com>
References: <CAG0JeshBZo=064058Pqs=UF+uWGhnWUNZqxY4yyRuJ7xy3DFGw@mail.gmail.com>
Message-ID: <20170804020316.GA35092@cskk.homeip.net>

Hi, and welcome to the tutor list.

Please try to provide a useful subject line in future posts (not "help", 
perhaps something like "I don't understand this TypeError message").

Anyway, to your question:

On 03Aug2017 13:27, Howard Lawrence <1019shaun at gmail.com> wrote:
>hi ! i am newbie to coding love it but need help with problems which i
>searched but poor results this is the error: typeError unorderable types:
>int()<str()

Please always include the entire error message with a text cut/paste; it 
usually contains lots of useful information.

The error above means that you have a "int" and a "str", and are trying to 
compare them. That is not supported.

>the code in short

Please always incode the full code, ideally something stripped down to the 
smallest program you can run which still produces the error. Often problems 
come from something which is omitted in a "from memory" description of the 
code, rather than the raw code itself.

>number=random.randint(1,20)
>guess=input()
>guess=int(guess)
>but when reach the line that says
>if guess<number:
>
>i get the error ! help

As remarked, you can't compare an int and a str; it is not meaningful.

Your code above _should_ have an int in the value of "guess". However, I 
suspect your code actually may look like this:

  number=random.randint(1,20)
  guess=input()
  guess_value=int(guess)
  if guess<number:

and theat you should have "guess_value" in the "if" condition, not "guess".

i.e. I'm suggesting that you haven't put the int into "guess" but into some 
other variable.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From 1019shaun at gmail.com  Fri Aug  4 07:11:06 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Fri, 4 Aug 2017 04:11:06 -0700
Subject: [Tutor] (regarding unorderable types
In-Reply-To: <CAG0Jesi8u437s0LQ+fS7cC=FUfRMLRfitPpCENONAWHCb8j_FQ@mail.gmail.com>
References: <CAG0JesjX51Ve+1a3ChmHNzyCoQLFtEyJRCkTfvGijrsaS8o36Q@mail.gmail.com>
 <CAG0Jesi8u437s0LQ+fS7cC=FUfRMLRfitPpCENONAWHCb8j_FQ@mail.gmail.com>
Message-ID: <CAG0JesiQD431E671KQU7LYyHUwAgJq7SSfxEXCtKZrs5j6QbsQ@mail.gmail.com>

Thank you for the clarification.
as a newbie at mailing list and coding
I try to be more specific,their is more to come

On Aug 3, 2017 10:09 PM, "Cameron Simpson" <cs at cskk.id.au> wrote:

Hi, and welcome to the tutor list.

Please try to provide a useful subject line in future posts (not "help",
perhaps something like "I don't understand this TypeError message").

Anyway, to your question:

On 03Aug2017 13:27, Howard Lawrence <1019shaun at gmail.com> wrote:

> hi ! i am newbie to coding love it but need help with problems which i
> searched but poor results this is the error: typeError unorderable types:
> int()<str()
>

Please always include the entire error message with a text cut/paste; it
usually contains lots of useful information.

The error above means that you have a "int" and a "str", and are trying to
compare them. That is not supported.

the code in short
>

Please always incode the full code, ideally something stripped down to the
smallest program you can run which still produces the error. Often problems
come from something which is omitted in a "from memory" description of the
code, rather than the raw code itself.

number=random.randint(1,20)
> guess=input()
> guess=int(guess)
> but when reach the line that says
> if guess<number:
>
> i get the error ! help
>

As remarked, you can't compare an int and a str; it is not meaningful.

Your code above _should_ have an int in the value of "guess". However, I
suspect your code actually may look like this:

 number=random.randint(1,20)
 guess=input()
 guess_value=int(guess)
 if guess<number:

and theat you should have "guess_value" in the "if" condition, not "guess".

i.e. I'm suggesting that you haven't put the int into "guess" but into some
other variable.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From guettliml at thomas-guettler.de  Fri Aug  4 06:15:21 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Fri, 4 Aug 2017 12:15:21 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <85a83gp354.fsf@benfinney.id.au>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
Message-ID: <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>



Am 04.08.2017 um 02:50 schrieb Ben Finney:
> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
> 
>> Why are there two ways: "script" vs "console_scripts entry-point"?
> 
> Because Distutils implements only ?scripts?, and that's not capable
> enough for what people need so Setuptools implements entry points.
> 
> In other words: One of them is in the standard library and does
> something; the other is third-party and can do more.
> 
> That answers why there are two. But maybe you wanted to ask some
> underlying question?

The underlaying question is: Imangine you are a newcomer. And there
are two more choices. You need a guide like 'if unsure do x'. With
other words: What is the sane default choice?

Chris wrote "Simple: `scripts` are legacy."

You say it is the standard, and console_scripts is from a third party.

For me "legacy" sound like "don't go this old way".

For me "third party" sounds like "don't go this way, stick to the standard".

I feel stupid since I have no clue.

Regards,
   Thomas G?ttler

-- 
Thomas Guettler http://www.thomas-guettler.de/

From eryksun at gmail.com  Fri Aug  4 13:26:43 2017
From: eryksun at gmail.com (eryk sun)
Date: Fri, 4 Aug 2017 17:26:43 +0000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
Message-ID: <CACL+1asKGkQgXm-GYnz3n6_PZfRc_D98=PsQGsCptzm8dGpYQQ@mail.gmail.com>

On Fri, Aug 4, 2017 at 10:15 AM, Thomas G?ttler
<guettliml at thomas-guettler.de> wrote:
> Am 04.08.2017 um 02:50 schrieb Ben Finney:
>
>> Because Distutils implements only ?scripts?, and that's not capable
>> enough for what people need so Setuptools implements entry points.
>>
>> In other words: One of them is in the standard library and does
>> something; the other is third-party and can do more.
>>
>> That answers why there are two. But maybe you wanted to ask some
>> underlying question?
>
> The underlaying question is: Imangine you are a newcomer. And there
> are two more choices. You need a guide like 'if unsure do x'. With
> other words: What is the sane default choice?

A newcomer should simply check for __name__ == "__main__". Learning
about packaging comes later.

> Chris wrote "Simple: `scripts` are legacy."
>
> You say it is the standard, and console_scripts is from a third party.

console_scripts and gui_scripts are installed by setuptools and pip,
which are developed under the umbrella of the Python Packaging
Authority [1]. The standard library also has the ensurepip [2] module
to install pip and setuptools. As third-party packages go, they're as
close to being 'standard' as you can get.

> For me "legacy" sound like "don't go this old way".

Legacy scripts aren't automatically created as console or GUI
executables when installed on Windows. Often Windows users associate
.py scripts with an editor, in which case legacy scripts aren't
executable from PATH, i.e. they have to be run as `python
legacy_script.py`, for example.

[1]: https://www.pypa.io
[2]: https://docs.python.org/3/library/ensurepip

From kwpolska at gmail.com  Fri Aug  4 14:51:15 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Fri, 4 Aug 2017 20:51:15 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
Message-ID: <CAMw+j7+m7tATi82udBtWe1A=HdX7Y90_r-h3QgTxeTXigLRjQw@mail.gmail.com>

On 4 August 2017 at 12:15, Thomas G?ttler <guettliml at thomas-guettler.de> wrote:
> Chris wrote "Simple: `scripts` are legacy."
>
> You say it is the standard, and console_scripts is from a third party.
>
> For me "legacy" sound like "don't go this old way".
>
> For me "third party" sounds like "don't go this way, stick to the standard".
>
> I feel stupid since I have no clue.

The official docs recommend distutils:

https://docs.python.org/2/library/distutils.html

> Most Python users will not want to use this module directly, but instead use the cross-version tools maintained by the Python Packaging Authority. In particular, setuptools is an enhanced alternative to distutils that provides:
> [snip]
> * the ability to declare project ?entry points?, which can be used as the basis for application plugin systems
> * the ability to automatically generate Windows command line executables at installation time rather than needing to prebuild them

And, as eryk sun mentioned, recent Python 2.7 and 3.4 versions ship
setuptools and pip, via the ensurepip module.

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From cs at cskk.id.au  Fri Aug  4 21:44:35 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 5 Aug 2017 11:44:35 +1000
Subject: [Tutor] Unorderable types
In-Reply-To: <CAG0JeshHEXcPnyuVckaqhcamT3CLvv+Yk-rzWGSvSRnbuhG_vg@mail.gmail.com>
References: <CAG0JeshHEXcPnyuVckaqhcamT3CLvv+Yk-rzWGSvSRnbuhG_vg@mail.gmail.com>
Message-ID: <20170805014435.GA3776@cskk.homeip.net>

[ Back onto the tutor list. - Cameron ]

On 04Aug2017 09:12, Howard Lawrence <1019shaun at gmail.com> wrote:
>This is the code from tutorial

Thank you.

>import random
>guessesTaken =0
>
>print ('hello what is your name')
>myName =input ()
>
>number = random.randint(1,20)
>print ('well, ' + myName + ', I am thinking of a number between 1 and 20')
>
>while guessesTaken < 6:
>    print ('take a guess')
>    guess=input ()
>    guess_value =int (guess)

Spooky :-) So you have "guess" containing the string from input(), and 
"guess_value" has the int.

>    guessesTaken = guessesTaken +1
>
>    If guess_value < number: # this is it
>        print('your guess is too low')

Strange, this should work. Btw, "If" should be lower case "if".

[...snip...]
># I changed all the "guess" to "guess_value" got the same result!
>
>This is it: traceback ( most recent call last):
>File "C:/User/Shaun/guessGame.py", line 19, in <module>
>If guess_value < number:
>typeError: unorderable types:int() < str ()

Interesting. Can you put this:

  print("type(guess_value) =", type(guess_value))
  print("type(number) =", type(number))

above that line and run it again? Because I just ran your code here and it 
worked for me.

>Hope this can help you and mostly me
>I don't wanna give up but help is scarce from my location

That's fine. The list is for help.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From robertvstepp at gmail.com  Fri Aug  4 23:00:36 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 4 Aug 2017 22:00:36 -0500
Subject: [Tutor] Unorderable types
In-Reply-To: <20170805014435.GA3776@cskk.homeip.net>
References: <CAG0JeshHEXcPnyuVckaqhcamT3CLvv+Yk-rzWGSvSRnbuhG_vg@mail.gmail.com>
 <20170805014435.GA3776@cskk.homeip.net>
Message-ID: <CANDiX9LECXgkXN6rrv9G9AGXOKNA=3gU=7XUEFJvyzdfWuvGeQ@mail.gmail.com>

On Fri, Aug 4, 2017 at 8:44 PM, Cameron Simpson <cs at cskk.id.au> wrote:
> [ Back onto the tutor list. - Cameron ]
>
> On 04Aug2017 09:12, Howard Lawrence <1019shaun at gmail.com> wrote:
>>
>> This is the code from tutorial
>
>
> Thank you.
>
>> import random
>> guessesTaken =0
>>
>> print ('hello what is your name')
>> myName =input ()
>>
>> number = random.randint(1,20)
>> print ('well, ' + myName + ', I am thinking of a number between 1 and 20')
>>
>> while guessesTaken < 6:
>>    print ('take a guess')
>>    guess=input ()
>>    guess_value =int (guess)
>
>
> Spooky :-) So you have "guess" containing the string from input(), and
> "guess_value" has the int.
>
>>    guessesTaken = guessesTaken +1
>>
>>    If guess_value < number: # this is it
>>        print('your guess is too low')
>
>
> Strange, this should work. Btw, "If" should be lower case "if".
>
> [...snip...]
>>
>> # I changed all the "guess" to "guess_value" got the same result!
>>
>> This is it: traceback ( most recent call last):
>> File "C:/User/Shaun/guessGame.py", line 19, in <module>
>> If guess_value < number:
>> typeError: unorderable types:int() < str ()

When I attempted to recreate his error message with the original code
snippets he sent, I got something a bit different:

================================================================================
py3: guess = input()
2
py3: guess < number
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'str' and 'int'
================================================================================

I am running Python 3.6.1 on Windows 7 64-bit.  Off-list Howard told
me that he is running Python 3.5 on Windows 7, using PyCharm as his
editor.

Did the text of this error message change between Python 3.5 and 3.6?
Could how he is using PyCharm -- a full-fledged Python IDE -- be
causing this problem?  I once tried out PyCharm a few years back, but
cannot recall if one has to save first before re-running the code from
within PyCharm in order for it to see the most recent version or not.


-- 
boB

From ben+python at benfinney.id.au  Sat Aug  5 00:14:01 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sat, 05 Aug 2017 14:14:01 +1000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info>
 <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
Message-ID: <85tw1modme.fsf@benfinney.id.au>

Thomas G?ttler <guettliml at thomas-guettler.de> writes:

> The underlaying question is: Imangine you are a newcomer.

A newcomer is in a tough position when it comes to packaging and
distributing Python code, especially the command-line programs.

There has been significant progress on this in recent years. The
Setuptools third-party library is a lot saner, the inclusion of ?pip? in
standard installs makes it much broader in scope.

But *not* in the standard library today, it's true.

> You need a guide like 'if unsure do x'. With other words: What is the
> sane default choice?

There isn't a good answer to that question, today.

The best answer today is: Read the guides from the Python Packaging
Authority, and stay abreast of developments because this continues to
change.

Maybe eventually the ongoing work of the PyPA will be settled enough
that it can update the standard library Distutils. But not today.

-- 
 \      ?Nothing is more sacred than the facts.? ?Sam Harris, _The End |
  `\                                                   of Faith_, 2004 |
_o__)                                                                  |
Ben Finney


From cs at cskk.id.au  Sat Aug  5 02:09:44 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 5 Aug 2017 16:09:44 +1000
Subject: [Tutor] Unorderable types
In-Reply-To: <CANDiX9LECXgkXN6rrv9G9AGXOKNA=3gU=7XUEFJvyzdfWuvGeQ@mail.gmail.com>
References: <CANDiX9LECXgkXN6rrv9G9AGXOKNA=3gU=7XUEFJvyzdfWuvGeQ@mail.gmail.com>
Message-ID: <20170805060944.GA21476@cskk.homeip.net>

On 04Aug2017 22:00, boB Stepp <robertvstepp at gmail.com> wrote:
>When I attempted to recreate his error message with the original code
>snippets he sent, I got something a bit different:
>
>================================================================================
>py3: guess = input()
>2
>py3: guess < number
>Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>TypeError: '<' not supported between instances of 'str' and 'int'
>================================================================================

I don't know about the text of the message, but his original snippets included 
a:

  guess = int(guess)

between those 2 lines.

Anyway, we have his current code, which i can't made produce the error.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From __peter__ at web.de  Sat Aug  5 03:01:36 2017
From: __peter__ at web.de (Peter Otten)
Date: Sat, 05 Aug 2017 09:01:36 +0200
Subject: [Tutor] Unorderable types
References: <CAG0JeshHEXcPnyuVckaqhcamT3CLvv+Yk-rzWGSvSRnbuhG_vg@mail.gmail.com>
 <20170805014435.GA3776@cskk.homeip.net>
 <CANDiX9LECXgkXN6rrv9G9AGXOKNA=3gU=7XUEFJvyzdfWuvGeQ@mail.gmail.com>
Message-ID: <om3qgb$rpi$1@blaine.gmane.org>

boB Stepp wrote:

> Did the text of this error message change between Python 3.5 and 3.6?

Yes:

$ python3.5 -c '1 < ""'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: unorderable types: int() < str()

$ python3.6 -c '1 < ""'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'str'



From bandagunda at hotmail.com  Fri Aug  4 16:03:35 2017
From: bandagunda at hotmail.com (banda gunda)
Date: Fri, 4 Aug 2017 20:03:35 +0000
Subject: [Tutor] file move with wait period
In-Reply-To: <20170804031858.GA23376@cskk.homeip.net>
References: <DB4PR06MB2974018BE019288F2508567DEB10@DB4PR06MB297.eurprd06.prod.outlook.com>,
 <20170804031858.GA23376@cskk.homeip.net>
Message-ID: <DB4PR06MB29707DE6A9A9DF72BDB5B58DEB60@DB4PR06MB297.eurprd06.prod.outlook.com>


Thanks Cameron (I hope I address your first name correctly).
Get Outlook for iOS<https://aka.ms/o0ukef>
________________________________
From: Cameron Simpson <cs at cskk.id.au>
Sent: Friday, August 4, 2017 5:18:58 AM
To: banda gunda
Cc: tutor at python.org
Subject: Re: [Tutor] file move with wait period

On 03Aug2017 11:22, banda gunda <bandagunda at hotmail.com> wrote:
>Dear tutors,
>
>I am interested to move a set of files, periodically, from source_folder to dest_folder.
>source_folder receives processed files from a ?decompressing program?.  The files are deposited from the ?decompressing program? at periodic random intervals.  Furthermore some of the files dropped in the source_folder are large, of typical size 800MB.  These files take time before it is completely deposited in the source_folder.
>
>I could use shutil.move (source_folder, dest_folder).  But then how?

You'd normally use shutil.move(source_file, dest_file) i.e. move individual
files. Or os.rename, but that requires that the source and dest are the same
filesystem.

>The frequency of moving files from source_folder to dest_folder is flexible.  It could be once in 15 minutes (or even lengthier).
>Challenge for me:  How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder?
>Thanks in advance for your comments/guidance.

That is the tricky thing; this shows up a lot, also with FTP upload locations
and so forth.

The problem, as you state, is knowing when the file is complete. There are 2
basic approaches: do not put a fil into the transfer directory before it is
complete, or to monitor the files for changes. On the premise that the file
will be being actively written until it is complete you could keep a list if
the files in the directory. For each name, record the file's size and
modification time. Wait for that to be unchanged "long enough"; you might then
decide it is ready to move.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From gsconyer at yahoo.com  Fri Aug  4 19:22:20 2017
From: gsconyer at yahoo.com (George Sconyers)
Date: Fri, 4 Aug 2017 23:22:20 +0000 (UTC)
Subject: [Tutor] Recommended Python Compiler
In-Reply-To: <CADrxXXkuNsRAQ78+0ZvtiBo4ime24mzpkc-k_NunukssOuc+Jw@mail.gmail.com>
References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com>
 <1285690201.2134862.1501453378125@mail.yahoo.com>
 <ollsfa$n7q$1@blaine.gmane.org>
 <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us>
 <oln8op$tr2$1@blaine.gmane.org> <oloab1$20r$1@blaine.gmane.org>
 <CAB3TsCj5h8Svh0avZtqNoXFVmYQeX+iUA5R663573PoyWR2EZA@mail.gmail.com>
 <CADrxXXkuNsRAQ78+0ZvtiBo4ime24mzpkc-k_NunukssOuc+Jw@mail.gmail.com>
Message-ID: <710983727.118233.1501888940020@mail.yahoo.com>

Thank you all for the feedback. As most of you pointed out I meant "IDE" instead of "compiler." ?There are a lot of options for me to check out this weekend. Looking forward to cracking a case of Mountain Dew and digging in.?
George


Sent from Yahoo Mail for iPhone


On Tuesday, August 1, 2017, 03:26, Abdur-Rahmaan Janhangeer <arj.python at gmail.com> wrote:

Yes indeed geany is a nice editor. I used it when i was beginning and even
wrote a post about it, Feel free to check it !

https://abdurrahmaanjanhangeer.wordpress.com/2016/11/02/python-getting-rid-of-identation-errors-quickly-checking-for-errors-and-the-use-of-editors/

On Tue, Aug 1, 2017 at 9:43 AM, Asokan Pichai <pasokan at gmail.com> wrote:

> For a simple beginners editor -- geany is a great choice.
>
> It can be used with minimal or no configuration/set up; and once
> you know your way around? you can tweak it as much as you want.
>
> It is easily installable on Debian/Ubuntu
>
>
> --
> Asokan Pichai
> *-------------------*
> We will find a way. Or, make one. (Hannibal)
> _______________________________________________
> Tutor maillist? -? Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
_______________________________________________
Tutor maillist? -? Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor




From xiaosong0911 at gmail.com  Sat Aug  5 03:23:57 2017
From: xiaosong0911 at gmail.com (Xiaosong Chen)
Date: Sat, 5 Aug 2017 15:23:57 +0800
Subject: [Tutor] how to make an lexical scope block?
Message-ID: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>

In C, it's a common pattern to use temporary variables in an lexical
scope to prevent the global scope from getting dirty.
For example,

```C
int a[N];
for (int i = 0; i < N; i++) {
  int temp = ...
  a[i] = ... // something got from temp
}
// temp do not exists here
```

But in python, such a pattern seems impossible. An straightforward
translation should be like this:

```python
a = []
for i in range(N):
    temp = ...
    a.append(...)# something got from temp
# temp DO EXISTS here, will be the value of the last iteration
```

As in the comment, the temporary variable remains existing after the
block. How do you usually deal with this?

From __peter__ at web.de  Sat Aug  5 05:28:14 2017
From: __peter__ at web.de (Peter Otten)
Date: Sat, 05 Aug 2017 11:28:14 +0200
Subject: [Tutor] how to make an lexical scope block?
References: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
Message-ID: <om433a$i4e$1@blaine.gmane.org>

Xiaosong Chen wrote:

> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.
> For example,
> 
> ```C
> int a[N];
> for (int i = 0; i < N; i++) {
>   int temp = ...
>   a[i] = ... // something got from temp
> }
> // temp do not exists here
> ```
> 
> But in python, such a pattern seems impossible. An straightforward
> translation should be like this:
> 
> ```python
> a = []
> for i in range(N):
>     temp = ...
>     a.append(...)# something got from temp
> # temp DO EXISTS here, will be the value of the last iteration
> ```
> 
> As in the comment, the temporary variable remains existing after the
> block. How do you usually deal with this?

I put the code into a function

def create_a(n):
    result = []
    for i in range(n):
        temp = ...
        result.append(...)
    return result

a = create_a(N)

At this point you could delete the function

del create_a

but in practice I never do that. 

If you want to go fancy you can rewrite the above as

def replace_with_result(*args, **kw):
    def call(f):
        return f(*args, **kw)
    return call

@replace_with_result(N)
def a(n):
    result = []
    for i in range(n):
        temp = ...
        result.append(...)
    return result

which will immediately overwrite the function a() with the result of the 
a(N) call -- but I prefer to keep the function around. 

The extra memory is usually negligible, and writing unit tests to detect 
blunders in create_a() is always a good idea, as trivial as it might appear 
on first sight...


From steve at pearwood.info  Sat Aug  5 05:38:56 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 5 Aug 2017 19:38:56 +1000
Subject: [Tutor] how to make an lexical scope block?
In-Reply-To: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
References: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
Message-ID: <20170805093855.GX3149@ando.pearwood.info>

On Sat, Aug 05, 2017 at 03:23:57PM +0800, Xiaosong Chen wrote:
> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.
[...]
> But in python, such a pattern seems impossible. An straightforward
> translation should be like this:
> 
> ```python
> a = []
> for i in range(N):
>     temp = ...
>     a.append(...)# something got from temp
> # temp DO EXISTS here, will be the value of the last iteration
> ```
> 
> As in the comment, the temporary variable remains existing after the
> block. How do you usually deal with this?


If you use functions (or methods), as you should, then temp will be a 
local variable of the function, and it doesn't matter if it still exists 
after the for loop. It is hidden inside the function scope, and cannot 
affect the global scope.

If you are using global scope, as sometimes is needed, then it depends. 
If this is a script that you run, then it really doesn't matter. A few 
temporary variables more or less doesn't make the script any better or 
worse. Don't worry about it.

If it is a library, where a nice clean global namespace is important, 
you can either refactor the code to make the problem go away, or delete 
the name when you are done:

del temp

deletes the name "temp" from the current namespace.

-- 
Steve

From alan.gauld at yahoo.co.uk  Sat Aug  5 08:22:48 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 5 Aug 2017 13:22:48 +0100
Subject: [Tutor] how to make an lexical scope block?
In-Reply-To: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
References: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
Message-ID: <om4dai$km5$1@blaine.gmane.org>

On 05/08/17 08:23, Xiaosong Chen wrote:
> In C, it's a common pattern to use temporary variables in an lexical
> scope to prevent the global scope from getting dirty.

This was very common in the early days of C - around 1979-1985 - when
compilers often only considered the first 4 (or 6) characters of a
variable name - even though the name itself could be 16 or 32
characters long.

Thus 'index' and 'indeterminate' and 'indent' were all seen
as the same name. This required careful limiting of the lexical
scope of variables. Nowadays I don't see that as an issue and
most of the C code I work with doesn't limit scope beyond
a function definition. Maybe some old school C programmers
still worry about tight scoping but not the ones I work with!

As for Python it limits names to global (actually module)
and function scope. If you are creating well structured
code based on short clear functions there should not be
much of a problem.

So, to answer the question,

1) we don't tend to need such scoping because the language
permits many names, and it provides module and function scopes.

2) Also we avoid importing with the

from foo import *

style which increases risks of name pollution.

3) We need fewer temporary variables because we can use
tuple unpacking and generator expressions to replace many
scenarios where C would use a temporary variable.

In practice I've never found it to be an issue.

HTH

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



From badouglas at gmail.com  Sat Aug  5 11:44:03 2017
From: badouglas at gmail.com (bruce)
Date: Sat, 5 Aug 2017 11:44:03 -0400
Subject: [Tutor] really basic question..
Message-ID: <CAP16ngooipS_n_Tr08fXWhwLKke2DV2CP031jHnqqHCK_8QtHQ@mail.gmail.com>

Hey guys.

A really basic question. I have the following:
      try:
        element = WebDriverWait(driver,
100).until(EC.presence_of_element_located((By.ID,
"remarketingStoreId")))
      except TimeoutException:
        driver.close()


I was wondering can I do something like the following to handle
"multiple" exceptions? Ie, have an "except" block that catches all
issues other than the specific TimeoutException.

      try:
        element = WebDriverWait(driver,
100).until(EC.presence_of_element_located((By.ID,
"remarketingStoreId")))
      except TimeoutException:
        driver.close()
      except :
        driver.close()


I've looked all over SO, as well as the net in general. I might have
ust missed what I was looking for though.

Comments??  Thanks much.

From badouglas at gmail.com  Sat Aug  5 11:48:58 2017
From: badouglas at gmail.com (bruce)
Date: Sat, 5 Aug 2017 11:48:58 -0400
Subject: [Tutor] really basic question..
In-Reply-To: <CAP16ngooipS_n_Tr08fXWhwLKke2DV2CP031jHnqqHCK_8QtHQ@mail.gmail.com>
References: <CAP16ngooipS_n_Tr08fXWhwLKke2DV2CP031jHnqqHCK_8QtHQ@mail.gmail.com>
Message-ID: <CAP16ngrBHhNbejsP0+8+k10ATCWco7fyNjnWg+9WBoyGRQHA0Q@mail.gmail.com>

Lord...

redid a search just now. found a bunch of sites that said it's
doable.. embarrased

Not sure what I was looking for earlier.. need r u m!



On Sat, Aug 5, 2017 at 11:44 AM, bruce <badouglas at gmail.com> wrote:
> Hey guys.
>
> A really basic question. I have the following:
>       try:
>         element = WebDriverWait(driver,
> 100).until(EC.presence_of_element_located((By.ID,
> "remarketingStoreId")))
>       except TimeoutException:
>         driver.close()
>
>
> I was wondering can I do something like the following to handle
> "multiple" exceptions? Ie, have an "except" block that catches all
> issues other than the specific TimeoutException.
>
>       try:
>         element = WebDriverWait(driver,
> 100).until(EC.presence_of_element_located((By.ID,
> "remarketingStoreId")))
>       except TimeoutException:
>         driver.close()
>       except :
>         driver.close()
>
>
> I've looked all over SO, as well as the net in general. I might have
> ust missed what I was looking for though.
>
> Comments??  Thanks much.

From alan.gauld at yahoo.co.uk  Sat Aug  5 12:43:36 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 5 Aug 2017 17:43:36 +0100
Subject: [Tutor] really basic question..
In-Reply-To: <CAP16ngrBHhNbejsP0+8+k10ATCWco7fyNjnWg+9WBoyGRQHA0Q@mail.gmail.com>
References: <CAP16ngooipS_n_Tr08fXWhwLKke2DV2CP031jHnqqHCK_8QtHQ@mail.gmail.com>
 <CAP16ngrBHhNbejsP0+8+k10ATCWco7fyNjnWg+9WBoyGRQHA0Q@mail.gmail.com>
Message-ID: <om4sjh$pv4$1@blaine.gmane.org>

On 05/08/17 16:48, bruce wrote:

> redid a search just now. found a bunch of sites that said it's
> doable.. embarrased

Just because its doable doesn't mean you should though...

Bare except clauses can hide a multitude of sins. Unless its
at the top level of your program and you use it to log
any errors that occur its probably a bad idea.

Much better to be as specific as possible and catch only
anticipated errors. Anything else will then cause a crash
and you can investigate the (unanticipated) cause.

Note, you can link multiple error types in a single
except clause

try:...
except Error1:...
except (Error2, Error3, Error4):....

HTH

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



From 1019shaun at gmail.com  Sat Aug  5 13:35:54 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Sat, 5 Aug 2017 10:35:54 -0700
Subject: [Tutor] unorderable types
In-Reply-To: <CAG0JeshQ5ZZGVF-mfzY4vYOCZJ-xY2=J=bBJMaLiGzAbi4dgMw@mail.gmail.com>
References: <CAG0JesgGqMcYR362ZGQV8BsEQPxuMWntsSrA_cj95RqW0aK+4A@mail.gmail.com>
 <CAG0Jesifm=nvyt9xUcZegLe6t+UdXW_GHWEaa5hG9cAnA9h3DQ@mail.gmail.com>
 <CAG0Jesh2+S0eqtZX7ZAzcmFyMx6T_HNcOLFEC-2ZvHiDMtkeNA@mail.gmail.com>
 <CAG0Jesir4yNPmaNL0X6kH9eco_ZfKsZE3CpY15uObv1gvkkXTw@mail.gmail.com>
 <CAG0Jesi7NHJpeFSH_DMrnYTw2C_fj5KTswBH-o=o0cGPUBZNvg@mail.gmail.com>
 <CAG0JesiprrcOaDMqD1_T-vmDvvSce7h_JztMKdCfVD4tdCLrOQ@mail.gmail.com>
 <CAG0Jesiot3k39=XrS263RksBsuUxcf7pu-d0AG8GQSSBq6vK9A@mail.gmail.com>
 <CAG0JesjE+Eb5nEBDCw9qCZqGmCh-Z1dBPKVhCi17Dc7vZiJn9w@mail.gmail.com>
 <CAG0Jesiv+R2h_ayeai53dv9z+Lbhs3NOpCT5Cmkfi5aRvs0CBQ@mail.gmail.com>
 <CAG0JesjtLw6PZHanPADP+y6j=kdynCWfcJM_-oTybfPFKtRo1A@mail.gmail.com>
 <CAG0JesieZAC_HA0TkYS=RsTwzSJN7bMoC2S9Z31nOpYd=-cUDg@mail.gmail.com>
 <CAG0Jesh3it7ukgNyhPHe8Q2th45CTXLzoe+SoD6Df4XmQrdc8A@mail.gmail.com>
 <CAG0JesiJ9MG0vXvy9m+fDqecYSC-BGzLzTcrf6i2Rx0+btOOCA@mail.gmail.com>
 <CAG0Jesi6S3pM8Zuk+-GW83NURWToGify4p3+z+CKy6i6Tst+kA@mail.gmail.com>
 <CAG0JesjUdzdjHHaOD10N4k89oQRJvPjs=UgXSNP8tZTOZ5V06Q@mail.gmail.com>
 <CAG0JesgNVzZ8xmZsc6JByCLH-Nm-fkobm9i1zOjF6tSZXgBkkQ@mail.gmail.com>
 <CAG0Jesj3RhgeOWgeg79-dNHKLwKJPOmF3QTMjJMF98oMOvjY_g@mail.gmail.com>
 <CAG0JeshnHx_si8isT=KDh8iVvuHgd4DB7mvLVMdH9ch3gAgDJQ@mail.gmail.com>
 <CAG0JesjQD=J2hkx+GnRkqVK-dFSjXwH6C_u+1wV6H_VPUzz9FA@mail.gmail.com>
 <CAG0Jesjtj1kAwuJeGxkt=u_7fkVbbuwZk6QVZPcYWKa=ed_gfg@mail.gmail.com>
 <CAG0JesgzFXk8fx6fCXzWxruFx94=piLp9CCM9Qh6TxOvdizzqw@mail.gmail.com>
 <CAG0JesgTuq3UKLax=hmjaPMs8BvDNG36YqON0OLtYTt57d_qaw@mail.gmail.com>
 <CAG0JesgT3pKRuu3mL9XUd-eJOaJ_JT_ZDjYngqv=he8ALnY7cg@mail.gmail.com>
 <CAG0JesjUOLPhJDsYoUky1-kK7hE4NeUwE5x41KkmFFZm-O-fjQ@mail.gmail.com>
 <CAG0JesgXPP4Cq0CRFWVZx-sGzC+hhAP31+LXW-hw9cfPjJyffQ@mail.gmail.com>
 <CAG0JesgxgJceCpv_n0xd=mCxapywpOCnuV9yqZ_FxEzDc5o-cw@mail.gmail.com>
 <CAG0JeshXa9Ca=Sp9jCV1bQ2tp8oG5a3SaphNuZEobq73_XPqsg@mail.gmail.com>
 <CAG0JeshYWA9NbEVea0VJxpoUCA1yG=0WNJW54-HAKm6cONZ2Fw@mail.gmail.com>
 <CAG0JesggTpUFBiTHw5t_7X=4z6Egw-YxEk74D_Z5_zep9cyjbA@mail.gmail.com>
 <CAG0JesjbWqt1ZwoF5npBAnaifMR6Y3Jc2V05QH8mdhYy=UjWag@mail.gmail.com>
 <CAG0JesintDoeT4maUOfKTpZfZRV0=DvDc8S43cJx6ABKP-dG=w@mail.gmail.com>
 <CAG0JesigLegU_1bpRsSc34D5zm9xMSOFc6mhXbcZm6uYY2DfPA@mail.gmail.com>
 <CAG0Jesg81a+OxGis3W2iOwjSNYy3+3H0Uk1c=BxSd3yTS6D6QA@mail.gmail.com>
 <CAG0Jesia-qX48pt-xgcHu-N8cD8gFDj3LAkc_4jbg3j+sXEn=g@mail.gmail.com>
 <CAG0Jesgmgic410FQMeLj9ozRk609G2gnPWy3nCKd49RT5Yp13g@mail.gmail.com>
 <CAG0JesjuCt_k955FRzJsJVDX+QoG+6+VL+EG_jM7WcoJo=jrww@mail.gmail.com>
 <CAG0Jesi-Rfmrxcznt5m8LVYF6Q1GfC7WAv+J8Eqxpep3Wa7cfg@mail.gmail.com>
 <CAG0JesizCTudvCBWCE76ovT09oRNuQeRxgKRtLFCTxM6RLB4zQ@mail.gmail.com>
 <CAG0JeshvaQ8-=75crm8F_djkoew6j-jffVfJQodRQpN3rG81Fw@mail.gmail.com>
 <CAG0JeshQ5ZZGVF-mfzY4vYOCZJ-xY2=J=bBJMaLiGzAbi4dgMw@mail.gmail.com>
Message-ID: <CAG0JeshYkuaxSkac6iF=xs2cTsickFJPOAgP==XBL9NOmDJcbg@mail.gmail.com>

Typing the : print("type (guess_value)=", type (guess_value))
print("type (number)=",type(number)

type (guess_value)= <class int>
type (number)= <class int>

==============================
the code runs again then prints
type guess_value =< class int>
type number=<class str>

=============================
Now Traceback kicks in
if guess_value < number:
TypeError : unorderable types: int() < str()
============================
Ran the code from Cmd prompt
Got TypeError not supported between
Instance of 'int' and 'str'
=============================
It's seems up till
If guess_value < number:
 guess_value is a integer
 also number which the computer generated
 =============================
Still scratching my head-:(

From 1019shaun at gmail.com  Sat Aug  5 14:28:22 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Sat, 5 Aug 2017 11:28:22 -0700
Subject: [Tutor] unorderable types
Message-ID: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>

# this is a guess number game.
import random

guessesTaken = 0

print('hello! What is your name?')
myName = input()

number = random.randint(1, 20)
print('Well, ' + myName + ', i am thinking of a number between 1 and 20')

while guessesTaken < 6:
    print('take a guess.')
    guess = input()
    guess_value = int(guess)

    guessesTaken = guessesTaken + 1

    print("type(guess_value)=",type(guess_value))
    print("type(number)=",type(number))

    if guess_value < number:
        print('your guess is too low.')

    if guess_value > number:
        print('your guess is too high.')

    if guess_value == number:
        break

    if guess_value == number:
       guessesTaken = str(guessesTaken)
       print ('good job, ' + myName + '! you guessed my number in ' +
guessesTaken + ' guesses!')

    if guess_value != number:
        number = str(number)
        print ('nope. the number i was thinking of was ' + number)

# this is a guess number game.
import random

guessesTaken = 0

print('hello! What is your name?')
myName = input()

number = random.randint(1, 20)
print('Well, ' + myName + ', i am thinking of a number between 1 and 20')

while guessesTaken < 6:
    print('take a guess.')
    guess = input()
    guess_value = int(guess)

    guessesTaken = guessesTaken + 1

    print("type(guess_value)=",type(guess_value))
    print("type(number)=",type(number))

    if guess_value < number:
        print('your guess is too low.')

    if guess_value > number:
        print('your guess is too high.')

    if guess_value == number:
        break

    if guess_value == number:
       guessesTaken = str(guessesTaken)
       print ('good job, ' + myName + '! you guessed my number in ' +
guessesTaken + ' guesses!')

    if guess_value != number:
        number = str(number)
        print ('nope. the number i was thinking of was ' + number)

# this is a guess number game.
import random

guessesTaken = 0

print('hello! What is your name?')
myName = input()

number = random.randint(1, 20)
print('Well, ' + myName + ', i am thinking of a number between 1 and 20')

while guessesTaken < 6:
    print('take a guess.')
    guess = input()
    guess_value = int(guess)

    guessesTaken = guessesTaken + 1

    print("type(guess_value)=",type(guess_value))
    print("type(number)=",type(number))

    if guess_value < number:
        print('your guess is too low.')

    if guess_value > number:
        print('your guess is too high.')

    if guess_value == number:
        break

    if guess_value == number:
       guessesTaken = str(guessesTaken)
       print ('good job, ' + myName + '! you guessed my number in ' +
guessesTaken + ' guesses!')

    if guess_value != number:
        number = str(number)
        print ('nope. the number i was thinking of was ' + number)

# this is a guess number game.
import random

guessesTaken = 0

print('hello! What is your name?')
myName = input()

number = random.randint(1, 20)
print('Well, ' + myName + ', i am thinking of a number between 1 and 20')

while guessesTaken < 6:
    print('take a guess.')
    guess = input()
    guess_value = int(guess)

    guessesTaken = guessesTaken + 1

    print("type(guess_value)=",type(guess_value))
    print("type(number)=",type(number))

    if guess_value < number:
        print('your guess is too low.')

    if guess_value > number:
        print('your guess is too high.')

    if guess_value == number:
        break

    if guess_value == number:
       guessesTaken = str(guessesTaken)
       print ('good job, ' + myName + '! you guessed my number in ' +
guessesTaken + ' guesses!')

    if guess_value != number:
        number = str(number)
        print ('nope. the number i was thinking of was ' + number)

# this is a guess number game.
import random

guessesTaken = 0

print('hello! What is your name?')
myName = input()

number = random.randint(1, 20)
print('Well, ' + myName + ', i am thinking of a number between 1 and 20')

while guessesTaken < 6:
    print('take a guess.')
    guess = input()
    guess_value = int(guess)

    guessesTaken = guessesTaken + 1

    print("type(guess_value)=",type(guess_value))
    print("type(number)=",type(number))

    if guess_value < number:
        print('your guess is too low.')

    if guess_value > number:
        print('your guess is too high.')

    if guess_value == number:
        break

    if guess_value == number:
       guessesTaken = str(guessesTaken)
       print ('good job, ' + myName + '! you guessed my number in ' +
guessesTaken + ' guesses!')

    if guess_value != number:
        number = str(number)
        print ('nope. the number i was thinking of was ' + number)

=================================================================================================
dont understand the error TypeError unorderable types 'int()' <' str()'
run the code from cmd prompt also error
inserted a print function before the first "if" statement
which return type (guess_value) = <class int>
type(number) = <class int>
================================================================================================
run the next line and  prints
type(guess_value) = int
type(number)=str


================================================================================================
from the cmd: the error is TypeError not supported between instance of
'int'  and 'str'

How do do i fix this ??, i typed it right from a tutorial

From alan.gauld at yahoo.co.uk  Sun Aug  6 02:19:25 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 6 Aug 2017 07:19:25 +0100
Subject: [Tutor] unorderable types
In-Reply-To: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
References: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
Message-ID: <om6cd6$ct0$1@blaine.gmane.org>

On 05/08/17 19:28, Howard Lawrence wrote:

>     if guess_value != number:
>         number = str(number)
>         print ('nope. the number i was thinking of was ' + number)

There is the problem, you convert number to a str before printing
it. so next iteration of the loop your if test fails.

You don't need the conversion in this case because print does it
automatically. If you did need it for some other purpose then
you should store the result in a temp variable rather than
in number itself.

This is a good example of why you should post the whole of your
code not just the snippet that you think is causing the problem...
If you had posted this in the first message we would probably
have spotted it right away.

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



From alan.gauld at yahoo.co.uk  Sun Aug  6 01:59:41 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 6 Aug 2017 06:59:41 +0100
Subject: [Tutor] how to make an lexical scope block?
In-Reply-To: <CAPA-TXC9E2fSD4n7gtrhV0jpBF1UV7RT3PfeTqUQiA8wO=jjgw@mail.gmail.com>
References: <CAPA-TXDxRK0ch9Wakc6ka2it==O=93+-Nup3g=pNcM-tZ6REuA@mail.gmail.com>
 <om4dai$km5$1@blaine.gmane.org>
 <CAPA-TXC9E2fSD4n7gtrhV0jpBF1UV7RT3PfeTqUQiA8wO=jjgw@mail.gmail.com>
Message-ID: <ba68a16b-801d-2e79-580e-e0fc971b8437@yahoo.co.uk>

CCing the list.
Always use ReplyAll or ReplyList when responding to the list.

On 05/08/17 18:17, Xiaosong Chen wrote:
> 2) Also we avoid importing with the
>> from foo import *
>>
>> even if you import with
>>
>> import foo
>>
>> foo.temp can still be accessed. When you use autocomplete in an
>> interactive shell like ipython, it might become an item.

foo.temp does not pose a problem of name pollution because you have
to prefix it with foo. Thus every module can have a temp variable and
there is no risk of names clashing because they all need to be
accessed with name.temp. You can even compare them:

if foo.temp < bar.temp....

> 3) We need fewer temporary variables because we can use
>> tuple unpacking and generator expressions to replace many
>> scenarios where C would use a temporary variable.
> I know little with python's xxx comprehension. In my memory, temporary
> variables seem not allowed inside, and the same for lambda
> expressions. Might you give some examples?
>
Things like list comprehensions often replace explicit loops which
would introduce extra named variables. Consider:

>>> lst = [n for n in range(7)]
>>> n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined
>>> lst
[0, 1, 2, 3, 4, 5, 6]
>>> lst2 = []
>>> for n in range(7): lst2.append(n)
...
>>> n
6
>>> lst2
[0, 1, 2, 3, 4, 5, 6]
>>>

You can see how in the list comprehension case n
is not visible outside the comprehension whereas n
exists outside the for loop(as you noted in your original
post) so, by using the comprehension we reduce
the number of visible names.


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


From cs at cskk.id.au  Sun Aug  6 03:40:02 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 6 Aug 2017 17:40:02 +1000
Subject: [Tutor] unorderable types
In-Reply-To: <om6cd6$ct0$1@blaine.gmane.org>
References: <om6cd6$ct0$1@blaine.gmane.org>
Message-ID: <20170806074002.GA29015@cskk.homeip.net>

On 06Aug2017 07:19, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:
>On 05/08/17 19:28, Howard Lawrence wrote:
>>     if guess_value != number:
>>         number = str(number)
>>         print ('nope. the number i was thinking of was ' + number)
>
>There is the problem, you convert number to a str before printing
>it. so next iteration of the loop your if test fails.
>
>You don't need the conversion in this case because print does it
>automatically.

I should point out that print doesn't magicly let you "+" a str and an int. You 
would need to write:

  print ('nope. the number i was thinking of was ', number)

You can see that that doesn't use "+". The print function calls str() on each 
of its arguments, then writes the result to the output. str() on the string 
returns itself, and str(number) returns the number in text form.

You can see then that you don't need str(number) yourself, and therefore do not 
need to store it in a variable.

Also, while you can bind a value of any type to any variable, as you have here 
by binding an int to "number" and then later a str to "number", it is not a 
great idea. A particular variable should usually always hold the same type of 
value; this storing of different types of values in the same variable 
contributed to your problem.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From robertvstepp at gmail.com  Sun Aug  6 13:35:46 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 6 Aug 2017 12:35:46 -0500
Subject: [Tutor] unorderable types
In-Reply-To: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
References: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
Message-ID: <CANDiX9L-VaomXwQQ+hKjA_WsWRaYzeisN75DZvFYsfo0uuHdhw@mail.gmail.com>

On Sat, Aug 5, 2017 at 1:28 PM, Howard Lawrence <1019shaun at gmail.com> wrote:
> # this is a guess number game.
> import random
>
> guessesTaken = 0
>
> print('hello! What is your name?')
> myName = input()
>
> number = random.randint(1, 20)
> print('Well, ' + myName + ', i am thinking of a number between 1 and 20')
>
> while guessesTaken < 6:
>     print('take a guess.')
>     guess = input()
>     guess_value = int(guess)
>
>     guessesTaken = guessesTaken + 1
>
>     print("type(guess_value)=",type(guess_value))
>     print("type(number)=",type(number))
>
>     if guess_value < number:
>         print('your guess is too low.')
>
>     if guess_value > number:
>         print('your guess is too high.')
>
>     if guess_value == number:
>         break

If the values are equal the "break" statement will exit your while
loop and never see the following "if" block.

>     if guess_value == number:
>        guessesTaken = str(guessesTaken)
>        print ('good job, ' + myName + '! you guessed my number in ' +
> guessesTaken + ' guesses!')

And I suspect you only want to execute the following "if" block if the
user did not guess the number in the provided six guesses.

>     if guess_value != number:
>         number = str(number)
>         print ('nope. the number i was thinking of was ' + number)

So these final two "if" groupings should be _outside_ your while loop:

while guessesTaken < 6:
    <All of your earlier code inside the while loop>

if guess_value == number:
    print('good job, ' + myName + '! you guessed my number in',
guessesTaken, 'guesses!')

else:
    print('nope. the number i was thinking of was', number)

Notice the differences in indentation between what is _inside_ the
while loop and what now follows _outside_ the while loop.  Also
instead of two consecutive "if" blocks, I used the "if - else"
structure.  If the "if" condition is not true then the code will
automatically execute the "else" block.  Per what the others have
said, I did not convert "guessesTaken" and "number" to strings,  The
print function will handle that for us.  Also, with the print function
if items to be printed are listed as separate arguments, that is,
separated by commas, the default behavior  of print is to insert a
single space in the place of each comma.

Inside your while loop you could use "if - elif - else" instead of
your chain of three "if" statements.  Have you read about these yet?
If yes, then it would be more natural (Pythonic) to do things this
way:

while guessesTaken < 6:
    ...
    if guess_value < number:
        ...
    elif guess_value > number:
        ...
    else:
        break

Hope all of this makes sense.  If not come back with questions.

Cheers!

boB

From mats at wichmann.us  Sun Aug  6 14:23:48 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 6 Aug 2017 12:23:48 -0600
Subject: [Tutor] unorderable types
In-Reply-To: <CANDiX9L-VaomXwQQ+hKjA_WsWRaYzeisN75DZvFYsfo0uuHdhw@mail.gmail.com>
References: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
 <CANDiX9L-VaomXwQQ+hKjA_WsWRaYzeisN75DZvFYsfo0uuHdhw@mail.gmail.com>
Message-ID: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us>

On 08/06/2017 11:35 AM, boB Stepp wrote:

> So these final two "if" groupings should be _outside_ your while loop:
> 
> while guessesTaken < 6:
>     <All of your earlier code inside the while loop>
> 
> if guess_value == number:
>     print('good job, ' + myName + '! you guessed my number in',
> guessesTaken, 'guesses!')
> 
> else:
>     print('nope. the number i was thinking of was', number)
> 
> Notice the differences in indentation between what is _inside_ the
> while loop and what now follows _outside_ the while loop.  Also
> instead of two consecutive "if" blocks, I used the "if - else"
> structure.  If the "if" condition is not true then the code will
> automatically execute the "else" block.  Per what the others have
> said, I did not convert "guessesTaken" and "number" to strings,  The
> print function will handle that for us.  Also, with the print function
> if items to be printed are listed as separate arguments, that is,
> separated by commas, the default behavior  of print is to insert a
> single space in the place of each comma.

Yes, to highlight this last comment, the code as written is building one
string to pass to print, in other words it is similar to doing:

x = chunk1 + chunk2 + chunk3
print(x)

of course there's no assignment to 'x' taking place, I just use that to
illustrate that print is called with one argument.

and Bob is suggesting you can also let print do the combining:

print(chunk1, chunk2, chunk3)

it which case it applies a little formatting work for you (inserting the
space).  There will be lots more options to string formatting for print.


Meanwhile, it is worth pointing out that while: (as with other python
loops) can take an else: clause, which is executed if the loop runs to
completion and was not exited via break.  That means you could ALSO
write (this is pseudo-code for brevity):

while guessesTaken < 6:
    collect_guess
    if guess_value == number
        break
    other_actions
else:
    print(guesses_ran_out)
    quit_program

# if we got here it's because a guess was correct
print(congratulations)

Using this is no more or less correct than not using it, just pointing
it out for your learning about Python loops.  Apparently some people
think while/else, for/else and so on are useless, or vile, or whatever.
But they're certainly a part of the language.



From robertvstepp at gmail.com  Sun Aug  6 16:20:07 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 6 Aug 2017 15:20:07 -0500
Subject: [Tutor] unorderable types
In-Reply-To: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us>
References: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
 <CANDiX9L-VaomXwQQ+hKjA_WsWRaYzeisN75DZvFYsfo0uuHdhw@mail.gmail.com>
 <178d3494-1a04-a36f-2599-e96094282460@wichmann.us>
Message-ID: <CANDiX9JWjJykAkFHn1OXKX8WNbKNVkM_je+ie3iKXZvoF7DG9Q@mail.gmail.com>

On Sun, Aug 6, 2017 at 1:23 PM, Mats Wichmann <mats at wichmann.us> wrote:

> Meanwhile, it is worth pointing out that while: (as with other python
> loops) can take an else: clause, which is executed if the loop runs to
> completion and was not exited via break.  That means you could ALSO
> write (this is pseudo-code for brevity):
>
> while guessesTaken < 6:
>     collect_guess
>     if guess_value == number
>         break
>     other_actions
> else:
>     print(guesses_ran_out)
>     quit_program
>
> # if we got here it's because a guess was correct
> print(congratulations)
>
> Using this is no more or less correct than not using it, just pointing
> it out for your learning about Python loops.  Apparently some people
> think while/else, for/else and so on are useless, or vile, or whatever.
> But they're certainly a part of the language.

Interesting.  I have seen else clauses for loops in the official
Python docs and books which try to be syntax-complete in their
presentation, but I cannot recall ever seeing this presented in
beginner and introduction books of which I have several [1].  Why is
this?  It does not seem a particularly difficult or confusing topic
and it can be useful.  Just wondering ...

[1]  An exception is "Beginning Python -- From Novice to Professional,
3rd ed." by Magnus Lie Hetland, c. 2017.  I recently acquired this
book and so far I am enjoying it.  I would not recommend it for a true
beginner to programming, but for anyone that has had any experience
programming in any language I think it might be a good read for such a
person to learn Python.  The author seems to bring in all of the
syntactic elements, either directly or in sidebars/sections that can
be skipped for later reading.  Perhaps unfortunately, he does not
provide many examples, thus making it fast-paced.  The latter section
of the book has ten substantial projects he goes through that have
mostly practical applications for real world examples, but if you have
any programming experience, this can be an advantage as such a person
probably does not need a lot of repetitive examples.  I might do a
more detailed review later once I finish the book to see if my initial
impression holds up.  But so far I wish it were the first Python book
I ever picked up!

-- 
boB

From robertvstepp at gmail.com  Sun Aug  6 16:25:19 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 6 Aug 2017 15:25:19 -0500
Subject: [Tutor] unorderable types
In-Reply-To: <CANDiX9JWjJykAkFHn1OXKX8WNbKNVkM_je+ie3iKXZvoF7DG9Q@mail.gmail.com>
References: <CAG0Jesj6ds4CMfo2W5MK8WWP00hUcv8mGqHrS+R+ZBfKc0s54Q@mail.gmail.com>
 <CANDiX9L-VaomXwQQ+hKjA_WsWRaYzeisN75DZvFYsfo0uuHdhw@mail.gmail.com>
 <178d3494-1a04-a36f-2599-e96094282460@wichmann.us>
 <CANDiX9JWjJykAkFHn1OXKX8WNbKNVkM_je+ie3iKXZvoF7DG9Q@mail.gmail.com>
Message-ID: <CANDiX9L0ON1E6bngx6bT6wKVsQQm-26GrDpZBJVMgVcYb88eYA@mail.gmail.com>

Curses!  I screwed up my later insertion.  I should have written in my footnote:

On Sun, Aug 6, 2017 at 3:20 PM, boB Stepp <robertvstepp at gmail.com> wrote:

> [1]  An exception is "Beginning Python -- From Novice to Professional,
> 3rd ed." by Magnus Lie Hetland, c. 2017.  I recently acquired this
> book and so far I am enjoying it.  I would not recommend it for a true
> beginner to programming, but for anyone that has had any experience
> programming in any language I think it might be a good read for such a
> person to learn Python.  The author seems to bring in all of the
> syntactic elements, either directly or in sidebars/sections that can
> be skipped for later reading.  Perhaps unfortunately, he does not
> provide many examples, thus making it fast-paced, but if you have
> any programming experience, this can be an advantage as such a person
> probably does not need a lot of repetitive examples.  The latter section
> of the book has ten substantial projects he goes through that have
> mostly practical applications for real world examples.   I might do a
> more detailed review later once I finish the book to see if my initial
> impression holds up.  But so far I wish it were the first Python book
> I ever picked up!
>
> --
> boB



-- 
boB

From robertvstepp at gmail.com  Sun Aug  6 19:35:10 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 6 Aug 2017 18:35:10 -0500
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
Message-ID: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>

I am looking more deeply into the subject of decorators for a bit (So
I can thoroughly digest Steve's information in the thread "basic
decorator question".) and have been first looking at static and class
methods.  As a start, I have tried the following:

=========================================================================================
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
py3: class MyClass:
...     def my_method():
...             print('This is my_method in MyClass!')
...
py3: class MyOtherClass:
...     @staticmethod
...     def my_other_method():
...             print('This is my_other_method in MyOtherClass!')
...
py3: MyClass.my_method()
This is my_method in MyClass!
py3: MyOtherClass.my_other_method()
This is my_other_method in MyOtherClass!
=========================================================================================

I see no difference in result, whether I use the @staticmethod decorator or not.

In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under
the entry "staticmethod(function)" the author states, "... Use the
@staticmethod functiion decorator in version 2.4 and later ... In
Python 3.X only, this built-in is not required for simple functions in
classes called only through class objects (and never through instance
objects)."  So what I am understanding is that I only need use the
@staticmethod decorator if I am using Python versions 2.4 through 2.7
(new-style classes).  Is my understanding correct?

TIA!

-- 
boB

From 1019shaun at gmail.com  Sun Aug  6 15:41:43 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Sun, 6 Aug 2017 12:41:43 -0700
Subject: [Tutor] Tutor Digest, Vol 162, Issue 19
In-Reply-To: <CAG0JesjXcoExfB7e6TiSo9MJWc94VwOdhh1hLSUe6ux068OaRQ@mail.gmail.com>
References: <mailman.12.1502035202.27001.tutor@python.org>
 <CAG0Jesgf4c=vmkr3n27mtbuQxX-nPMscqy8Tf=GwDW_PVhs0NA@mail.gmail.com>
 <CAG0JesjXcoExfB7e6TiSo9MJWc94VwOdhh1hLSUe6ux068OaRQ@mail.gmail.com>
Message-ID: <CAG0JeshF_gbe7dJNdje4yKoT1kjh0dxUHjrKNPwex1opyWEc_Q@mail.gmail.com>

On Aug 6, 2017 11:00 AM, <tutor-request at python.org> wrote:

Send Tutor mailing list submissions to
        tutor at python.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://mail.python.org/mailman/listinfo/tutor
or, via email, send a message with subject or body 'help' to
        tutor-request at python.org

You can reach the person managing the list at
        tutor-owner at python.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Tutor digest..."

Today's Topics:

   1. Re: unorderable types (Cameron Simpson)


---------- Forwarded message ----------
From: Cameron Simpson <cs at cskk.id.au>
To: tutor at python.org
Cc:
Bcc:
Date: Sun, 6 Aug 2017 17:40:02 +1000
Subject: Re: [Tutor] unorderable types
On 06Aug2017 07:19, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:

> On 05/08/17 19:28, Howard Lawrence wrote:
>
>>     if guess_value != number:
>>         number = str(number)
>>         print ('nope. the number i was thinking of was ' + number)
>>
>
> There is the problem, you convert number to a str before printing
> it. so next iteration of the loop your if test fails.
>
> You don't need the conversion in this case because print does it
> automatically.
>

I should point out that print doesn't magicly let you "+" a str and an int.
You would need to write:

 print ('nope. the number i was thinking of was ', number)

You can see that that doesn't use "+". The print function calls str() on
each of its arguments, then writes the result to the output. str() on the
string returns itself, and str(number) returns the number in text form.

You can see then that you don't need str(number) yourself, and therefore do
not need to store it in a variable.

Also, while you can bind a value of any type to any variable, as you have
here by binding an int to "number" and then later a str to "number", it is
not a great idea. A particular variable should usually always hold the same
type of value; this storing of different types of values in the same
variable contributed to your problem.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

Thanks for everything,it's running

     saw where storing two different types in the same variable!
   Digesting your pointers !


_______________________________________________
Tutor maillist  -  Tutor at python.org
https://mail.python.org/mailman/listinfo/tutor

From alan.gauld at yahoo.co.uk  Sun Aug  6 20:06:27 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 7 Aug 2017 01:06:27 +0100
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
Message-ID: <om8ats$a73$1@blaine.gmane.org>

On 07/08/17 00:35, boB Stepp wrote:

> =========================================================================================
> Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64
> bit (AMD64)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
> py3: class MyClass:
> ...     def my_method():
> ...             print('This is my_method in MyClass!')
> ...
> py3: class MyOtherClass:
> ...     @staticmethod
> ...     def my_other_method():
> ...             print('This is my_other_method in MyOtherClass!')
> ...
> py3: MyClass.my_method()
> This is my_method in MyClass!
> py3: MyOtherClass.my_other_method()
> This is my_other_method in MyOtherClass!

You should also try calling them from an instance of the class.
That should also illustrate a difference between classmethod and
staticmethod when you get round to that.

> the entry "staticmethod(function)" the author states, "... Use the
> @staticmethod functiion decorator in version 2.4 and later ... In
> Python 3.X only, this built-in is not required for simple functions in
> classes called only through class objects (and never through instance
> objects)."  

Notice the bit in parens...
It doesn't say you cannot call staticmethods from instances,
it says that you don;t need the decorator unless you are
doing that. Very different.

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



From eryksun at gmail.com  Sun Aug  6 20:43:06 2017
From: eryksun at gmail.com (eryk sun)
Date: Mon, 7 Aug 2017 00:43:06 +0000
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
Message-ID: <CACL+1auA4bXBM0d=KUHTu6gd5swdHqqg_mY4xAQPaWhtNgL3+w@mail.gmail.com>

On Sun, Aug 6, 2017 at 11:35 PM, boB Stepp <robertvstepp at gmail.com> wrote:
>
> I see no difference in result, whether I use the @staticmethod decorator or not.

While a staticmethod and a function are both descriptors [1], a
staticmethod is basically a no-op descriptor. Its __get__ method
always returns its unbound callable (i.e. its __func__ attribute)
instead of returning a computed property or bound method.

Examples

    >>> descr = vars(MyOtherClass)['my_other_method']
    >>> descr
    <staticmethod object at 0x7f558d7846d8>

    >>> descr.__func__
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

When accessed as an attribute of a class (i.e. the instance argument
passed to __get__ is None), a staticmethod returns just its __func__.

    >>> descr.__get__(None, MyOtherClass)
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

That's effectively no different from a Python 3 function. But they
diverge when accessed as an attribute of an instance. In this case the
__get__ method of a staticmethod also simply returns its __func__,

    >>> descr.__get__(MyOtherClass(), MyOtherClass)
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

whereas the __get__ method of a function returns a method that's bound
to the instance.

    >>> func = vars(MyClass)['my_method']
    >>> func
    <function MyClass.my_method at 0x7f558d7858c8>

    >>> func.__get__(MyClass(), MyClass)
    <bound method MyClass.my_method of
        <__main__.MyClass object at 0x7f558d7847f0>>

[1]: https://docs.python.org/3/reference/datamodel.html#implementing-descriptors

From guettliml at thomas-guettler.de  Mon Aug  7 02:40:30 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Mon, 7 Aug 2017 08:40:30 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <85tw1modme.fsf@benfinney.id.au>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
Message-ID: <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>



Am 05.08.2017 um 06:14 schrieb Ben Finney:
> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
> 
>> The underlaying question is: Imangine you are a newcomer.
> 
> A newcomer is in a tough position when it comes to packaging and
> distributing Python code, especially the command-line programs.
> 
> There has been significant progress on this in recent years. The
> Setuptools third-party library is a lot saner, the inclusion of ?pip? in
> standard installs makes it much broader in scope.
> 
> But *not* in the standard library today, it's true.
> 
>> You need a guide like 'if unsure do x'. With other words: What is the
>> sane default choice?
> 
> There isn't a good answer to that question, today.
> 
> The best answer today is: Read the guides from the Python Packaging
> Authority, and stay abreast of developments because this continues to
> change.
> 
> Maybe eventually the ongoing work of the PyPA will be settled enough
> that it can update the standard library Distutils. But not today.
> 

You say that there isn't a good answer to that question, today.

For me the question was: setup.py "script" vs "console_scripts" ?

I found this: https://packaging.python.org/tutorials/distributing-packages/#console-scripts

You say that there isn't a good answer to that question, today.

I can't follow.

Why is "the sane default is 'use console_scripts entry-point in setup.py'" not a good answer?

Regards,
   Thomas G?ttler



-- 
Thomas Guettler http://www.thomas-guettler.de/

From steve at pearwood.info  Mon Aug  7 09:36:35 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 7 Aug 2017 23:36:35 +1000
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
Message-ID: <20170807133634.GB3149@ando.pearwood.info>

On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote:

> py3: class MyClass:
> ...     def my_method():
> ...             print('This is my_method in MyClass!')
> ...
> py3: class MyOtherClass:
> ...     @staticmethod
> ...     def my_other_method():
> ...             print('This is my_other_method in MyOtherClass!')
> ...
> py3: MyClass.my_method()
> This is my_method in MyClass!
> py3: MyOtherClass.my_other_method()
> This is my_other_method in MyOtherClass!

A small comment: since the methods have different names, there's no 
reason why they couldn't both be in the same class. 

It is hard to see the distinction between an ordinary method and a 
static method from this example. What you are seeing is, by accident, 
the equivalent of just writing:

def my_method():
    print('This is my_method in MyClass!')

outside of the class and calling the bare function. Notice that despite 
the name, my_method is not *actually* usable as a method. It has no 
"self" parameter.


> I see no difference in result, whether I use the @staticmethod decorator or not.

Indeed you would not, because you are calling MyClass.my_method, 
directly from the class object. If you created an instance first, and 
then called the methods, you would see a big difference!

obj = MyClass()
obj.my_method()  # fails with TypeError, as there is no "self" parameter

while the staticmethod would succeed.

So what's going on here?

When you call MyClass.my_method, Python looks up my_method on the class 
object, equivalent to:

    thing = getattr(MyClass, 'my_method')

before calling thing(), which then prints the message.

This is where is gets complex... Python performs some special magic when 
you look up attributes, according to "the descriptor protocol". Don't 
worry about how it works -- think of it as black magic for now. But the 
bottom line is, if the look up returns something like a string or an int 
or a list, no descriptor magic happens, but if it returns a function 
(something you created with "def"), something not far removed from this 
happens:

    # (instance) method descriptor
    if thing is a function:
        if the source was a class # like "MyClass.method":
            # This was different in Python 2.
            return thing, unchanged
        else:  # source was an instance, "MyClass().method"
            wrap thing in a method object that receives "self"
            return the method object

Why does it bother? Because that way Python can automatically fill in 
the instance as "self".

Example: today we write:

    s = "Hello world!"
    t = s.upper()

But without this method magic, or something similar, we would have to 
write:

    s = "Hello world!"
    t = str.upper(s)  # need to manually provide "self"

or even:

    s = "Hello world!"
    t = s.upper(s)

in order for the upper() method to receive the instance s as the "self" 
parameter.

Despite the name, your example "my_method" isn't a method and doesn't 
require "self". If you try to pass one in, you get a TypeError because 
the function doesn't take any arguments at all. But normally methods 
need to know what instance they are working on, in other words, they 
need to know "self".

So when you call MyClass.my_method, calling from the class, Python just 
gives you the raw function object, unchanged. Normally that means you 
would need to provide "self" yourself. This is called an "unbound 
method", it's unbound because it doesn't know what instance to work on.

Example:

    str.upper

is the equivalent of an unbound method. It is incomplete, because it 
doesn't know what string to uppercase. You have to provide one for it to 
work on:

    str.upper("spam")

But if you call directly from an instance, Python knows what string to 
use as "self", and you don't need to do any more:

    "spam".upper()


Unbound methods have their uses. In Python 2, they were actual custom 
method objects, but in Python 3 it was decided that this was pointless 
and instead the bare function is returned instead. But conceptually, the 
base function is an unbound method.

So normal methods convert a function to a method which automatically 
provides "self", but only if called from the instance (self). Otherwise 
they return the function, which needs you to manually provide self.

In your example, by accident (I assume?) you forgot to include "self", 
so the fact that no self was provided didn't stop the function from 
working.

Now, how about class methods? Class methods are just like ordinary 
(instance) methods, except instead of "self", they receive the class 
object as first parameter. There aren't many good examples of class 
methods, and so they aren't common. But here's one:

    dict.fromkeys

Most dict methods (update, pop, popitem, clear, etc.) need to know which 
specific dict to work on. But fromkeys is different: it does not care 
what instance you use. Both of these will work exactly the same:

    {}.fromkeys(['one', 'two', 'three'])
    {100: 'A', 200: 'B', 300: 'C'}.fromkeys(['one', 'two', 'three'])

The instance is so unimportant that fromkeys can be equally called from 
the dict class itself:

    dict.fromkeys(['one', 'two', 'three'])

Instead of the instance, "self", fromkeys receives the class, "cls". In 
this case, it will be dict, but if you subclass:

class MyDict(dict):
    pass

MyDict.fromkeys(['one', 'two', 'three'])

then the fromkeys method sees *your* class, MyDict, instead of dict. To 
make your own functions that behave like fromkeys, you decorate them 
with the `classmethod` built-in:

class MyClass(object):
    @classmethod
    def method(cls, arg):
        ...

When you use classmethod, the behaviour you see is something like:

    # classmethod descriptor
    if thing is a function:
        wrap thing in a classmethod object that receives "cls"
        return the classmethod object


Finally we come to static methods, which use the `staticmethod` 
decorator. Static methods sometimes are confusing, because:

(1) There are very, very few good uses for static methods in Python. If 
you think you need a static method, you probably could just use a 
regular module-level function.

(2) In Java, "static method" refers to something which is more like 
Python's *class methods*, so people with Java experience sometimes use 
the wrong one.

What does staticmethod do? Basically, it's just a protective decorator 
which prevents the default instance method behaviour from happening. It 
does something like:

    # staticmethod descriptor
    if thing is a function:
        return thing, unchanged


> In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under
> the entry "staticmethod(function)" the author states, "... Use the
> @staticmethod functiion decorator in version 2.4 and later ... In
> Python 3.X only, this built-in is not required for simple functions in
> classes called only through class objects (and never through instance
> objects)."  So what I am understanding is that I only need use the
> @staticmethod decorator if I am using Python versions 2.4 through 2.7
> (new-style classes).  Is my understanding correct?

What Mark is saying here is that in Python 2, if you want the static 
method functionality, you have to use the staticmethod decorator:

class MyClass(object):
    @staticmethod
    def func(arg):  # no self, no cls
        ...


But in Python 3, you can leave it out, *provided* you never call

instance = MyClass()
instance.func(x)  # TypeError

but only 

MyClass.func(x)


I don't know why he bothered to mention that. The fact that this works 
at all is an accident, not something to rely on.




-- 
Steve

From robertvstepp at gmail.com  Mon Aug  7 21:22:40 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 7 Aug 2017 20:22:40 -0500
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <20170807133634.GB3149@ando.pearwood.info>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
 <20170807133634.GB3149@ando.pearwood.info>
Message-ID: <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>

I feel like I have gazed into a crystal clear pool, apparently
shallow, with many interesting objects (Pun intended!) on the pool
floor.  Interested in these beautiful things, I jump in to grab one
for close-up study only to find that the pool is much, ... , much
deeper (> 1 boB-height) than it appeared.  And alas!  I don't know how
to swim!

On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote:
>
>> py3: class MyClass:
>> ...     def my_method():
>> ...             print('This is my_method in MyClass!')
>> ...
>> py3: class MyOtherClass:
>> ...     @staticmethod
>> ...     def my_other_method():
>> ...             print('This is my_other_method in MyOtherClass!')
>> ...
>> py3: MyClass.my_method()
>> This is my_method in MyClass!
>> py3: MyOtherClass.my_other_method()
>> This is my_other_method in MyOtherClass!
>
> A small comment: since the methods have different names, there's no
> reason why they couldn't both be in the same class.

As I did not know exactly where I was going with these exploratory
examples, I thought I would keep things separated in case something
surprising developed.  Then I could easily compare the two.

> It is hard to see the distinction between an ordinary method and a
> static method from this example. What you are seeing is, by accident,
> the equivalent of just writing:
>
> def my_method():
>     print('This is my_method in MyClass!')
>
> outside of the class and calling the bare function. Notice that despite
> the name, my_method is not *actually* usable as a method. It has no
> "self" parameter.

I thought that was the whole essence of static methods -- no self parameter.

>
>> I see no difference in result, whether I use the @staticmethod decorator or not.
>
> Indeed you would not, because you are calling MyClass.my_method,
> directly from the class object. If you created an instance first, and
> then called the methods, you would see a big difference!

Alan pointed out I might want to investigate this.  I did and got what
you show below.

> obj = MyClass()
> obj.my_method()  # fails with TypeError, as there is no "self" parameter
>
> while the staticmethod would succeed.
>
> So what's going on here?
>
> When you call MyClass.my_method, Python looks up my_method on the class
> object, equivalent to:
>
>     thing = getattr(MyClass, 'my_method')
>
> before calling thing(), which then prints the message.
>
> This is where is gets complex... Python performs some special magic when
> you look up attributes, according to "the descriptor protocol". Don't
> worry about how it works -- think of it as black magic for now. But the
> bottom line is, if the look up returns something like a string or an int
> or a list, no descriptor magic happens, but if it returns a function
> (something you created with "def"), something not far removed from this
> happens:
>
>     # (instance) method descriptor
>     if thing is a function:
>         if the source was a class # like "MyClass.method":
>             # This was different in Python 2.
>             return thing, unchanged
>         else:  # source was an instance, "MyClass().method"
>             wrap thing in a method object that receives "self"
>             return the method object
>
> Why does it bother? Because that way Python can automatically fill in
> the instance as "self".

[snip]

>
> Despite the name, your example "my_method" isn't a method and doesn't
> require "self". If you try to pass one in, you get a TypeError because
> the function doesn't take any arguments at all. But normally methods
> need to know what instance they are working on, in other words, they
> need to know "self".

Question(s):  While something like "my_method" can't be called from an
object instance, it can be called on the class.  Are there use cases
where this behavior is actually desired?  If wrapped with
"@staticmethod" then there are two ways of calling the method, using
objects or using the class.  Is there some reason not to use the
"ClassName.a_static_method()" syntax?  Are there intended uses for
doing this?

> So when you call MyClass.my_method, calling from the class, Python just
> gives you the raw function object, unchanged. Normally that means you
> would need to provide "self" yourself. This is called an "unbound
> method", it's unbound because it doesn't know what instance to work on.

[snip]

> Unbound methods have their uses. In Python 2, they were actual custom
> method objects, but in Python 3 it was decided that this was pointless
> and instead the bare function is returned instead. But conceptually, the
> base function is an unbound method.
>
> So normal methods convert a function to a method which automatically
> provides "self", but only if called from the instance (self). Otherwise
> they return the function, which needs you to manually provide self.
>
> In your example, by accident (I assume?) ...

No, on purpose.  I was just playing around to see what would or would
not happen.

> ... you forgot to include "self",
> so the fact that no self was provided didn't stop the function from
> working.
>
> Now, how about class methods? Class methods are just like ordinary
> (instance) methods, except instead of "self", they receive the class
> object as first parameter. There aren't many good examples of class
> methods, and so they aren't common. But here's one:
>
>     dict.fromkeys
>
> Most dict methods (update, pop, popitem, clear, etc.) need to know which
> specific dict to work on. But fromkeys is different: it does not care
> what instance you use. Both of these will work exactly the same:
>
>     {}.fromkeys(['one', 'two', 'three'])
>     {100: 'A', 200: 'B', 300: 'C'}.fromkeys(['one', 'two', 'three'])
>
> The instance is so unimportant that fromkeys can be equally called from
> the dict class itself:
>
>     dict.fromkeys(['one', 'two', 'three'])
>
> Instead of the instance, "self", fromkeys receives the class, "cls". In
> this case, it will be dict, but if you subclass:
>
> class MyDict(dict):
>     pass
>
> MyDict.fromkeys(['one', 'two', 'three'])
>
> then the fromkeys method sees *your* class, MyDict, instead of dict. To
> make your own functions that behave like fromkeys, you decorate them
> with the `classmethod` built-in:
>
> class MyClass(object):
>     @classmethod
>     def method(cls, arg):
>         ...
>
> When you use classmethod, the behaviour you see is something like:
>
>     # classmethod descriptor
>     if thing is a function:
>         wrap thing in a classmethod object that receives "cls"
>         return the classmethod object

Class methods look to be something I will find difficult to find a use for.

>
> Finally we come to static methods, which use the `staticmethod`
> decorator. Static methods sometimes are confusing, because:
>
> (1) There are very, very few good uses for static methods in Python. If
> you think you need a static method, you probably could just use a
> regular module-level function.

This is how I am currently seeing things.


>> In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under
>> the entry "staticmethod(function)" the author states, "... Use the
>> @staticmethod functiion decorator in version 2.4 and later ... In
>> Python 3.X only, this built-in is not required for simple functions in
>> classes called only through class objects (and never through instance
>> objects)."  So what I am understanding is that I only need use the
>> @staticmethod decorator if I am using Python versions 2.4 through 2.7
>> (new-style classes).  Is my understanding correct?
>
> What Mark is saying here is that in Python 2, if you want the static
> method functionality, you have to use the staticmethod decorator:
>
> class MyClass(object):
>     @staticmethod
>     def func(arg):  # no self, no cls
>         ...
>
>
> But in Python 3, you can leave it out, *provided* you never call
>
> instance = MyClass()
> instance.func(x)  # TypeError
>
> but only
>
> MyClass.func(x)

Between you and Alan, I understand his comments now.

>
> I don't know why he bothered to mention that. The fact that this works
> at all is an accident, not something to rely on.

Not knowing Mr. Lutz, except through his books, he strikes me as a
very thorough person.

Thanks, Steve!  Your examples helped a lot.  Between this post of
yours and the other one in the thread "basic decorator question", I
think I have a decent handle on the ideas, if not all the details.
And Eryk's answer did push me to dip my toe into the descriptor pool a
little bit.  I think a lot of dedicated study on my part will be
needed on these topics.



-- 
boB

From ben+python at benfinney.id.au  Mon Aug  7 21:30:52 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Tue, 08 Aug 2017 11:30:52 +1000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info>
 <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
Message-ID: <85efsmn8vn.fsf@benfinney.id.au>

Thomas G?ttler <guettliml at thomas-guettler.de> writes:

> Why is "the sane default is 'use console_scripts entry-point in
> setup.py'" not a good answer?

Because third-party Setuptools is required for entry points, which means
entry points cannot be a default choice.

It may well be a good choice for many cases. But that's a different
matter from it being a good *default* choice; it can only be a default
choice if it's in the standard library.

-- 
 \       ?The best in us does not require the worst in us: Our love of |
  `\     other human beings does not need to be nurtured by delusion.? |
_o__)                             ?Sam Harris, at _Beyond Belief 2006_ |
Ben Finney


From robertvstepp at gmail.com  Mon Aug  7 22:44:09 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 7 Aug 2017 21:44:09 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
Message-ID: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>

py3: s = 'Hello!'
py3: len(s.encode("UTF-8"))
6
py3: len(s.encode("UTF-16"))
14
py3: len(s.encode("UTF-32"))
28

How is len() getting these values?  And I am sure it will turn out not
to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm
...

-- 
boB

From ben+python at benfinney.id.au  Mon Aug  7 23:01:22 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Tue, 08 Aug 2017 13:01:22 +1000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
Message-ID: <85zibalq4d.fsf@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> writes:

> How is len() getting these values?

By asking the objects themselves to report their length. You are
creating different objects with different content::

    >>> s = 'Hello!'
    >>> s_utf8 = s.encode("UTF-8")
    >>> s == s_utf8
    False
    >>> s_utf16 = s.encode("UTF-16")
    >>> s == s_utf16
    False
    >>> s_utf32 = s.encode("UTF-32")
    >>> s == s_utf32
    False

So it shouldn't be surprising that, with different content, they will
have different length::

    >>> type(s), len(s)
    (<class 'str'>, 6)
    >>> type(s_utf8), len(s_utf8)
    (<class 'bytes'>, 6)
    >>> type(s_utf16), len(s_utf16)
    (<class 'bytes'>, 14)
    >>> type(s_utf32), len(s_utf32)
    (<class 'bytes'>, 28)

What is it you think ?str.encode? does?

-- 
 \              ?In the long run, the utility of all non-Free software |
  `\      approaches zero. All non-Free software is a dead end.? ?Mark |
_o__)                                                    Pilgrim, 2006 |
Ben Finney


From zachary.ware+pytut at gmail.com  Mon Aug  7 23:04:21 2017
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Mon, 7 Aug 2017 22:04:21 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
Message-ID: <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>

On Mon, Aug 7, 2017 at 9:44 PM, boB Stepp <robertvstepp at gmail.com> wrote:
> py3: s = 'Hello!'
> py3: len(s.encode("UTF-8"))
> 6
> py3: len(s.encode("UTF-16"))
> 14
> py3: len(s.encode("UTF-32"))
> 28
>
> How is len() getting these values?  And I am sure it will turn out not
> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm

First, make sure you know exactly what is having its length checked.
In each of those cases, you're not checking the length of the string,
`s`, you're checking the length of the string `s` encoded in various
encodings (try each of those lines without the 'len' part).

Next, take a dive into the wonderful* world of Unicode:

https://nedbatchelder.com/text/unipain.html
https://www.youtube.com/watch?v=7m5JA3XaZ4k

Hope this helps,
-- 
Zach

From cs at cskk.id.au  Mon Aug  7 23:20:12 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 8 Aug 2017 13:20:12 +1000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
Message-ID: <20170808032012.GA79127@cskk.homeip.net>

On 07Aug2017 21:44, boB Stepp <robertvstepp at gmail.com> wrote:
>py3: s = 'Hello!'
>py3: len(s.encode("UTF-8"))
>6
>py3: len(s.encode("UTF-16"))
>14
>py3: len(s.encode("UTF-32"))
>28
>
>How is len() getting these values?  And I am sure it will turn out not
>to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm

The result of str.encode is a bytes object with the specified encoding of the 
original text.

Your sample string contains only ASCII characters, which encode 1-to-1 in 
UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others have 
a slight twist. Let's see:

    Python 3.6.1 (default, Apr 24 2017, 06:17:09)
    [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> s = 'Hello!'
    >>> s.encode()
    b'Hello!'
    >>> s.encode('utf-16')
    b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00'
    >>> s.encode('utf-32')
    b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00'

The utf-8 encoding (the default) is as you would expect.

The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte sequences 
as you might expect. Unlike the UTF-8 encoding, however, it is necessary to to 
know whether these byte sequences are big-endian (most significant byte first) 
or little-endian (least significant byte first).

The machine I'm on here is writing big endian UTF-16 and UTF-32.

As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This is 
because each encoding has a leading byte order marker to indicate the big 
endianness or little endianness. For big endian data that is \xff\xfe; for 
little endian data it would be \xfe\xff.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From eryksun at gmail.com  Tue Aug  8 00:30:31 2017
From: eryksun at gmail.com (eryk sun)
Date: Tue, 8 Aug 2017 04:30:31 +0000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <20170808032012.GA79127@cskk.homeip.net>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <20170808032012.GA79127@cskk.homeip.net>
Message-ID: <CACL+1avT7Sz_ofUoT29yxcfZyn5PSj15zS_2Y0yg7fmrcm95xA@mail.gmail.com>

On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson <cs at cskk.id.au> wrote:
>
> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
> is because each encoding has a leading byte order marker to indicate the big
> endianness or little endianness. For big endian data that is \xff\xfe; for
> little endian data it would be \xfe\xff.

To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g.

    >>> 'Hello!'.encode('utf-16le')
    b'H\x00e\x00l\x00l\x00o\x00!\x00'

Sometimes a data format includes the byte order, which makes using a
BOM redundant. For example, strings in the Windows registry use
UTF-16LE, without a BOM.

From cs at cskk.id.au  Tue Aug  8 02:59:07 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 8 Aug 2017 16:59:07 +1000
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
References: <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
Message-ID: <20170808065907.GA11195@cskk.homeip.net>

On 07Aug2017 20:22, boB Stepp <robertvstepp at gmail.com> wrote:
>On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano <steve at pearwood.info> wrote:
[...]
>> It is hard to see the distinction between an ordinary method and a
>> static method from this example. What you are seeing is, by accident,
>> the equivalent of just writing:
>>
>> def my_method():
>>     print('This is my_method in MyClass!')
>>
>> outside of the class and calling the bare function. Notice that despite
>> the name, my_method is not *actually* usable as a method. It has no
>> "self" parameter.
>
>I thought that was the whole essence of static methods -- no self parameter.

The point of a static method is that it doesn't have an instance or class 
context (a method's first argument).

A method gets called like this:

  obj.method(blah)

where obj is an instance of the class and blah is some arguments.

A method can be defined, essentially, 3 ways:

  def method(self, blah):

  @classmethod
  def method(klass, blah):

  @staticmethod
  def method(blah):

They all can be _called_ the same way. The decorator controls what context they 
receive. An ordinary method gets the instance ("obj", above) as its first 
argument as context. A class method receives the instance's class as its first 
argument as context. A static method gets no context, and no presupplied 
parameter.

What Steven is getting at is that if you define a method like this:

  def my_method():

is is supposed to be an ordinary method. However, orderinary methods are handed 
the instance ("obj") as the first parameter, and you have specified no 
parameter. This will blow up when you call it:

  class K(object):
    def m():
      pass

  o=K()
  o.m()
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  TypeError: m() takes 0 positional arguments but 1 was given

This is because m() is an ordinary method, and therefore it gets called with 
"o" as the first parameter. But it doesn't expect that, hence the TypeError.

Now, you _can_ call m() via the class:

  K.m()

but the point of classmethods and staticmethods is that you can call them on 
instances, and the caller doesn't need to know what style of method they are.  
The caller just goes:

  K.m(blah)

and doesn't care.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From alan.gauld at yahoo.co.uk  Tue Aug  8 03:39:08 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 8 Aug 2017 08:39:08 +0100
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
 <20170807133634.GB3149@ando.pearwood.info>
 <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
Message-ID: <ombpql$9k8$1@blaine.gmane.org>

On 08/08/17 02:22, boB Stepp wrote:

> "@staticmethod" then there are two ways of calling the method, using
> objects or using the class.  Is there some reason not to use the
> "ClassName.a_static_method()" syntax?  Are there intended uses for
> doing this?

classes are objects too...

You could have a list of objects, some of which are classes
and some instances.

Its nice to use polymorphism and just call the staticmethod (or
classmethod) and let the interpreter do the hard work without
having to test types - a nasty non-OO style of programming that
should be avoided if possible

> Class methods look to be something I will find difficult to find a use for.

Once you start using objects a lot they come in very useful.
I don't think I've built any significant OO system without
using at least a few class methods. Remember that class methods
conceptually act on the class as a whole - ie on all instances
both current and future. So any time you have a large group
of objects and you want to set some kind of state for all
of them you can use classmethods to set class state. Instance
methods can refer to the class state and modify their behaviour
accordingly. (Some OO gurus argue that you should only set
class state via a class method, although you can do it via an
instance too - but what if you need to set it when no
instances exist. In Python direct access allows that
from outside the class, but in other OO systems you need
a class method.)

Class methods are also the best place to put alternate
constructors - eg loading from a database given an
instance ID or by parsing a string representation.

Class methods can also be used to manage caches of instances,
do global searches of instances (eg from a database) etc.

>> (1) There are very, very few good uses for static methods in Python. If
>> you think you need a static method, you probably could just use a
>> regular module-level function.

Amen to that, I try to avoid staticmethods... and so far
have never found a valid use for one. I treat them as a
piece of legacy from earlier versions, prior to classmethods.

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



From __peter__ at web.de  Tue Aug  8 04:24:19 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 08 Aug 2017 10:24:19 +0200
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
 <20170807133634.GB3149@ando.pearwood.info>
 <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
 <ombpql$9k8$1@blaine.gmane.org>
Message-ID: <ombsfi$hlq$1@blaine.gmane.org>

Alan Gauld via Tutor wrote:

> classes are objects too...

Also, classes are instances. Given

>>> class Foo:
...     pass
... 
>>> foo = Foo()
>>> type(foo)
<class '__main__.Foo'>
>>> type(Foo)
<class 'type'>

what is the type of the type of the type ... of foo?
The answer is a circular definition that you cannot spell in Python itself:

>>> type(type)
<class 'type'>

The type of type is... type. Put the other way round: like ordinary classes 
type is an instance of type.


From cs at cskk.id.au  Tue Aug  8 05:14:22 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 8 Aug 2017 19:14:22 +1000
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <ombpql$9k8$1@blaine.gmane.org>
References: <ombpql$9k8$1@blaine.gmane.org>
Message-ID: <20170808091422.GA33365@cskk.homeip.net>

On 08Aug2017 08:39, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:
>>> (1) There are very, very few good uses for static methods in Python. If
>>> you think you need a static method, you probably could just use a
>>> regular module-level function.
>
>Amen to that, I try to avoid staticmethods... and so far
>have never found a valid use for one. I treat them as a
>piece of legacy from earlier versions, prior to classmethods.

I use them a bit for things that _could_ be module level functions, but using a 
static method lets me (a) associate if with a class and (b) one gets access to 
the method when one imports the class. So one can write code like this:

  from my_module import SomeDataFormat

  with open(datafile) as f:
    header_info = SomeDataFormat.parse_header(f)

and the module's SomeDataFormat class might have:

  class Foo:

    @staticmethod
    def parse_header(f):
      # decode the header structure and return info about it

That could easily be a standalone module function, but if the header record is 
a specific to the class then one can expose the parser function as a static 
method: it comes in with the class when it is imported, and it is clear that 
the parser is for what the class manages. It lets you avoid 
cumber_long_function_names because the "SomeDataFormat." contributes to the 
description.

I've also used them for factories, but think a class method is better. Thus:

  class Foo:

    def __init__(self, x, y, z):
      self.x = x
      self.y = y
      self.z = z

    @staticmethod
    def from_point(p):
      return Foo(p.x, p.y, p.z)

so that one can make a Foo directly:

  f = Foo(1,2,3)

or from some hypothetical "point" object:

  f = Foo.from_point(p)

But arguably this would be better as a class method anyway:

  @classmethod
  def from_point(klass, p):
    return klass(p.x, p.y, p.z)

because it lets you subclass Foo:

  class Bah(Foo):

and call Bah.from_point(p) for free, and it will make a Bah instead of a Foo 
because it gets the class as "klass".

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From kwpolska at gmail.com  Tue Aug  8 06:56:56 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Tue, 8 Aug 2017 12:56:56 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <85efsmn8vn.fsf@benfinney.id.au>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
Message-ID: <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>

On 8 August 2017 at 03:30, Ben Finney <ben+python at benfinney.id.au> wrote:
> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
>
>> Why is "the sane default is 'use console_scripts entry-point in
>> setup.py'" not a good answer?
>
> Because third-party Setuptools is required for entry points, which means
> entry points cannot be a default choice.
>
> It may well be a good choice for many cases. But that's a different
> matter from it being a good *default* choice; it can only be a default
> choice if it's in the standard library.

While setuptools is not officially part of the stdlib, it *is*
recommended by the official documentation, the dev team, and it?s
available pretty much everywhere. setuptools can?t be in stdlib,
because it?s moving too fast for stdlib to keep up.

Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on
PyPI use wheels. It means that at least that many use setuptools;
sometimes with a distutils fallback, but often without one. Moreover,
many of the packages without wheels use setuptools as well.

The sane default choice is entry_points.

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From robertvstepp at gmail.com  Tue Aug  8 23:17:49 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:17:49 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <85zibalq4d.fsf@benfinney.id.au>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <85zibalq4d.fsf@benfinney.id.au>
Message-ID: <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>

On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
> boB Stepp <robertvstepp at gmail.com> writes:
>
>> How is len() getting these values?
>
> By asking the objects themselves to report their length. You are
> creating different objects with different content::
>
>     >>> s = 'Hello!'
>     >>> s_utf8 = s.encode("UTF-8")
>     >>> s == s_utf8
>     False
>     >>> s_utf16 = s.encode("UTF-16")
>     >>> s == s_utf16
>     False
>     >>> s_utf32 = s.encode("UTF-32")
>     >>> s == s_utf32
>     False
>
> So it shouldn't be surprising that, with different content, they will
> have different length::
>
>     >>> type(s), len(s)
>     (<class 'str'>, 6)
>     >>> type(s_utf8), len(s_utf8)
>     (<class 'bytes'>, 6)
>     >>> type(s_utf16), len(s_utf16)
>     (<class 'bytes'>, 14)
>     >>> type(s_utf32), len(s_utf32)
>     (<class 'bytes'>, 28)
>
> What is it you think ?str.encode? does?

It is translating the Unicode code points into bits patterned by the
encoding specified.  I know this.  I was reading some examples from a
book and it was demonstrating the different lengths resulting from
encoding into UTF-8, 16 and 32.  I was mildly surprised that len()
even worked on these encoding results.  But for the life of me I can't
figure out for UTF-16 and 18 how these lengths are determined.  For
instance just looking at a single character:

py3: h = 'h'
py3: h16 = h.encode("UTF-16")
py3: h16
b'\xff\xfeh\x00'
py3: len(h16)
4

>From Cameron's response, I know that \xff\xfe is a Big-Endian BOM.
But in my mind 0xff takes up 4 bytes as each hex digit occupies
16-bits of space.  Likewise 0x00 looks to be 4 bytes -- Is this
representing EOL?  So far I have 8 bytes for the BOM and 4 bytes for
what I am guessing is the end-of-the-line for a byte length of 12 and
I haven't even gotten to the "h" yet!  So my question is actually as
stated:  For these encoded bytes, how are these lengths calculated?



-- 
boB

From robertvstepp at gmail.com  Tue Aug  8 23:23:28 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:23:28 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
Message-ID: <CANDiX9JUJgk3bjtu+mC2O67jY4qwnVZTkpa3zovdD=99W=MZAA@mail.gmail.com>

On Mon, Aug 7, 2017 at 10:04 PM, Zachary Ware
<zachary.ware+pytut at gmail.com> wrote:

> Next, take a dive into the wonderful* world of Unicode:
>
> https://nedbatchelder.com/text/unipain.html
> https://www.youtube.com/watch?v=7m5JA3XaZ4k
>
> Hope this helps,

Thanks, Zach, this actually clarifies things considerably.  I just
finished watching both videos.  Ned's made me aware of some
differences in Python 2 that will be very helpful at work if I ever
get into non-ASCII characters, as my lowest Python version there is
2.4.  And I thought that the second video author (Whose name I'd have
to look up the appropriate code points to type it here!) filled in
technical points that Ned alluded to, but did not explicitly cover.
The two together complemented each other nicely.

I was only vaguely aware of the Python 2 surprises until these two
videos gave more detail.


-- 
boB

From mats at wichmann.us  Tue Aug  8 23:29:43 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Tue, 08 Aug 2017 21:29:43 -0600
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <85zibalq4d.fsf@benfinney.id.au>
 <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>
Message-ID: <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us>

eh? the bytes are  ff fe h 0 
0xff is not literally four bytes, its the hex repr of an 8bit quantity with all bits on 

On August 8, 2017 9:17:49 PM MDT, boB Stepp <robertvstepp at gmail.com> wrote:
>On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney
><ben+python at benfinney.id.au> wrote:
>> boB Stepp <robertvstepp at gmail.com> writes:
>>
>>> How is len() getting these values?
>>
>> By asking the objects themselves to report their length. You are
>> creating different objects with different content::
>>
>>     >>> s = 'Hello!'
>>     >>> s_utf8 = s.encode("UTF-8")
>>     >>> s == s_utf8
>>     False
>>     >>> s_utf16 = s.encode("UTF-16")
>>     >>> s == s_utf16
>>     False
>>     >>> s_utf32 = s.encode("UTF-32")
>>     >>> s == s_utf32
>>     False
>>
>> So it shouldn't be surprising that, with different content, they will
>> have different length::
>>
>>     >>> type(s), len(s)
>>     (<class 'str'>, 6)
>>     >>> type(s_utf8), len(s_utf8)
>>     (<class 'bytes'>, 6)
>>     >>> type(s_utf16), len(s_utf16)
>>     (<class 'bytes'>, 14)
>>     >>> type(s_utf32), len(s_utf32)
>>     (<class 'bytes'>, 28)
>>
>> What is it you think ?str.encode? does?
>
>It is translating the Unicode code points into bits patterned by the
>encoding specified.  I know this.  I was reading some examples from a
>book and it was demonstrating the different lengths resulting from
>encoding into UTF-8, 16 and 32.  I was mildly surprised that len()
>even worked on these encoding results.  But for the life of me I can't
>figure out for UTF-16 and 18 how these lengths are determined.  For
>instance just looking at a single character:
>
>py3: h = 'h'
>py3: h16 = h.encode("UTF-16")
>py3: h16
>b'\xff\xfeh\x00'
>py3: len(h16)
>4
>
>From Cameron's response, I know that \xff\xfe is a Big-Endian BOM.
>But in my mind 0xff takes up 4 bytes as each hex digit occupies
>16-bits of space.  Likewise 0x00 looks to be 4 bytes -- Is this
>representing EOL?  So far I have 8 bytes for the BOM and 4 bytes for
>what I am guessing is the end-of-the-line for a byte length of 12 and
>I haven't even gotten to the "h" yet!  So my question is actually as
>stated:  For these encoded bytes, how are these lengths calculated?
>
>
>
>-- 
>boB
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

From robertvstepp at gmail.com  Tue Aug  8 23:30:53 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:30:53 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <20170808032012.GA79127@cskk.homeip.net>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <20170808032012.GA79127@cskk.homeip.net>
Message-ID: <CANDiX9J0M=ZQeV=MsOQ2+Uo0jcvCGif4q+RhHMGW=2GRsFR1ug@mail.gmail.com>

On Mon, Aug 7, 2017 at 10:20 PM, Cameron Simpson <cs at cskk.id.au> wrote:
> On 07Aug2017 21:44, boB Stepp <robertvstepp at gmail.com> wrote:
>>
>> py3: s = 'Hello!'
>> py3: len(s.encode("UTF-8"))
>> 6
>> py3: len(s.encode("UTF-16"))
>> 14
>> py3: len(s.encode("UTF-32"))
>> 28
>>
>> How is len() getting these values?  And I am sure it will turn out not
>> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm
>
>
> The result of str.encode is a bytes object with the specified encoding of
> the original text.
>
> Your sample string contains only ASCII characters, which encode 1-to-1 in
> UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others
> have a slight twist. Let's see:
>
>    Python 3.6.1 (default, Apr 24 2017, 06:17:09)
>    [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
>    Type "help", "copyright", "credits" or "license" for more information.
>    >>> s = 'Hello!'
>    >>> s.encode()
>    b'Hello!'
>    >>> s.encode('utf-16')
>    b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00'
>    >>> s.encode('utf-32')
>
> b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00'
>
> The utf-8 encoding (the default) is as you would expect.
>
> The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte
> sequences as you might expect. Unlike the UTF-8 encoding, however, it is
> necessary to to know whether these byte sequences are big-endian (most
> significant byte first) or little-endian (least significant byte first).

As I just posted in my response to Ben, I am missing something
probably quite basic in translating the bytes representation above
into "bytes".

> The machine I'm on here is writing big endian UTF-16 and UTF-32.
>
> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
> is because each encoding has a leading byte order marker to indicate the big
> endianness or little endianness. For big endian data that is \xff\xfe; for
> little endian data it would be \xfe\xff.

The arithmetic as I mentioned in my original post is what I am
expecting in "bytes", but my current thinking is that if I have for
the BOM you point out "\xff\xfe", I translate that as 4 hex digits,
each having 16 bits, for a total of 64 bits or 8 bytes.  What am I
misunderstanding here?  Is a definition of "byte" meaning something
other than 8 bits here?  I vaguely recall reading somewhere that
"byte" can mean different numbers of bits in different contexts.

And is len() actually counting "bytes" or something else for these encodings?


-- 
boB

From robertvstepp at gmail.com  Tue Aug  8 23:36:22 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:36:22 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CACL+1avT7Sz_ofUoT29yxcfZyn5PSj15zS_2Y0yg7fmrcm95xA@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <20170808032012.GA79127@cskk.homeip.net>
 <CACL+1avT7Sz_ofUoT29yxcfZyn5PSj15zS_2Y0yg7fmrcm95xA@mail.gmail.com>
Message-ID: <CANDiX9+zG-tK5PB-i0yqOevU=m9Ff4orNteSGo-JycyOrvhFHw@mail.gmail.com>

On Mon, Aug 7, 2017 at 11:30 PM, eryk sun <eryksun at gmail.com> wrote:
> On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson <cs at cskk.id.au> wrote:
>>
>> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
>> is because each encoding has a leading byte order marker to indicate the big
>> endianness or little endianness. For big endian data that is \xff\xfe; for
>> little endian data it would be \xfe\xff.
>
> To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g.
>
>     >>> 'Hello!'.encode('utf-16le')
>     b'H\x00e\x00l\x00l\x00o\x00!\x00'

If I do this, then I guess it becomes my responsibility to use the
correct "le" or "be" suffix when I later decode these bytes back into
Unicode code points.

> Sometimes a data format includes the byte order, which makes using a
> BOM redundant. For example, strings in the Windows registry use
> UTF-16LE, without a BOM.

Are there Windows bobby-traps that I need to watch out for because of
this?  I already know that the code pages that cmd.exe uses have
caused me some grief in displaying (or not displaying!) code points
which I have wanted to use.



-- 
boB

From robertvstepp at gmail.com  Tue Aug  8 23:43:13 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:43:13 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <85zibalq4d.fsf@benfinney.id.au>
 <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>
 <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us>
Message-ID: <CANDiX9JB0y=2NcjqrXAnzd_YqcippUyNM4fKshgy2mOg1UAb8A@mail.gmail.com>

On Tue, Aug 8, 2017 at 10:29 PM, Mats Wichmann <mats at wichmann.us> wrote:
> eh? the bytes are ff fe h 0
> 0xff is not literally four bytes, its the hex repr of an 8bit quantity with
> all bits on

ARGHHHH!  1111 1111 (space inserted for visual clarity) truly is ff in
hex.  Again ARGH!!!

All I can say is that I have not had to consciously think in bits,
octal or hex in quite a few years.  Oh, well.  You were quite nice in
pointing out my grave mental lapses!

Red-faced!
boB

From robertvstepp at gmail.com  Tue Aug  8 23:53:53 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 22:53:53 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <85zibalq4d.fsf@benfinney.id.au>
 <CANDiX9L3mKkak4q9pa+t00s6i57OmWJxck20K-frGFRTCgCDcg@mail.gmail.com>
Message-ID: <CANDiX9+JXaxJAfaS0JuE_BMmCn_muNbX1JNwrOjbJierAySP9A@mail.gmail.com>

On Tue, Aug 8, 2017 at 10:17 PM, boB Stepp <robertvstepp at gmail.com> wrote:
> On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
>> boB Stepp <robertvstepp at gmail.com> writes:
>>
>>> How is len() getting these values?
>>

>
> It is translating the Unicode code points into bits patterned by the
> encoding specified.  I know this.  I was reading some examples from a
> book and it was demonstrating the different lengths resulting from
> encoding into UTF-8, 16 and 32.  I was mildly surprised that len()
> even worked on these encoding results.  But for the life of me I can't
> figure out for UTF-16 and 18 how these lengths are determined.  For
> instance just looking at a single character:
>
> py3: h = 'h'
> py3: h16 = h.encode("UTF-16")
> py3: h16
> b'\xff\xfeh\x00'
> py3: len(h16)
> 4

This all makes perfect sense, arithmetic-wise, now that Matt has made
me realize my hex arithmetic was quite deficient!  And that makes
sense of the trailing "\x00", too (NOT an EOL char.).


-- 
boB

From robertvstepp at gmail.com  Wed Aug  9 00:17:38 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 8 Aug 2017 23:17:38 -0500
Subject: [Tutor] Difference(s) betweenPython 3 static methods with and
 without @staticmethod?
In-Reply-To: <ombpql$9k8$1@blaine.gmane.org>
References: <CANDiX9L52rACOzBndwhPUY3w1AJJ2uF6x3trXKMyb0NxXrAZnQ@mail.gmail.com>
 <20170807133634.GB3149@ando.pearwood.info>
 <CANDiX9L80eeGhfXdwD87amNVtc55_yzAo=r5fxRoCmD1gnX8yw@mail.gmail.com>
 <ombpql$9k8$1@blaine.gmane.org>
Message-ID: <CANDiX9+hCjSd9x51mBQAkyEpEZ4i9eQWRf1835+5SXZJq7TZPA@mail.gmail.com>

On Tue, Aug 8, 2017 at 2:39 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 08/08/17 02:22, boB Stepp wrote:

[snip lots of good stuff]

I am coming to the conclusion I need to code a substantial,
challenging project using OOP techniques, instead of just the toy
programs I have been playing around with so far.  When I do so, I
think I will start to see where all these different Python tools are
useful when I perceive I have a practical problem which reminds me of
one of these tools.

Thanks, Alan!


-- 
boB

From cs at cskk.id.au  Tue Aug  8 23:48:58 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 9 Aug 2017 13:48:58 +1000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9J0M=ZQeV=MsOQ2+Uo0jcvCGif4q+RhHMGW=2GRsFR1ug@mail.gmail.com>
References: <CANDiX9J0M=ZQeV=MsOQ2+Uo0jcvCGif4q+RhHMGW=2GRsFR1ug@mail.gmail.com>
Message-ID: <20170809034858.GA7198@cskk.homeip.net>

On 08Aug2017 22:30, boB Stepp <robertvstepp at gmail.com> wrote:
>On Mon, Aug 7, 2017 at 10:20 PM, Cameron Simpson <cs at cskk.id.au> wrote:
>> On 07Aug2017 21:44, boB Stepp <robertvstepp at gmail.com> wrote:
>>> py3: s = 'Hello!'
>>> py3: len(s.encode("UTF-8"))
>>> 6
>>> py3: len(s.encode("UTF-16"))
>>> 14
>>> py3: len(s.encode("UTF-32"))
>>> 28
>>>
>>> How is len() getting these values?  And I am sure it will turn out not
>>> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm
>>
>> The result of str.encode is a bytes object with the specified encoding of
>> the original text.
>>
>> Your sample string contains only ASCII characters, which encode 1-to-1 in
>> UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others
>> have a slight twist. Let's see:
>>
>>    Python 3.6.1 (default, Apr 24 2017, 06:17:09)
>>    [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
>>    Type "help", "copyright", "credits" or "license" for more information.
>>    >>> s = 'Hello!'
>>    >>> s.encode()
>>    b'Hello!'
>>    >>> s.encode('utf-16')
>>    b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00'
>>    >>> s.encode('utf-32')
>>    b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00'
[...]
>As I just posted in my response to Ben, I am missing something
>probably quite basic in translating the bytes representation above
>into "bytes".
>
>> The machine I'm on here is writing big endian UTF-16 and UTF-32.
>>
>> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
>> is because each encoding has a leading byte order marker to indicate the big
>> endianness or little endianness. For big endian data that is \xff\xfe; for
>> little endian data it would be \xfe\xff.
>
>The arithmetic as I mentioned in my original post is what I am
>expecting in "bytes", but my current thinking is that if I have for
>the BOM you point out "\xff\xfe", I translate that as 4 hex digits,
>each having 16 bits, for a total of 64 bits or 8 bytes.  What am I
>misunderstanding here?

A hex digit expresses 4 bits, not 16. "Hex"/"hexadecimal" is base 16, but that 
is 2^4, so just four bits per hex digit. So the BOM is 2 bytes long in UTF-16 
and 4 bytes long (\xff\xfe\x00\x00) in UTF-32.

>Is a definition of "byte" meaning something
>other than 8 bits here?  I vaguely recall reading somewhere that
>"byte" can mean different numbers of bits in different contexts.

There used to be machines with different "word" or "memory cell" sizes, size as 
6 or 9 bits etc, and these were still referred to as bytes. They're pretty much 
defunct, and these days the word "byte" always means 8 bits unless someone goes 
out of their way to say otherwise.

You'll find all the RFCs talk about "octets" for this very reason: a value 
consisting of 8 bits ("oct" meaning 8).

>And is len() actually counting "bytes" or something else for these encodings?

Just bytes, exactly as you expect.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From guettliml at thomas-guettler.de  Wed Aug  9 10:39:44 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Wed, 9 Aug 2017 16:39:44 +0200
Subject: [Tutor] The sane default choice is entry_points console_scripts
 Was: if __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de>
 <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au>
 <20170802035138.GK3149@ando.pearwood.info>
 <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de>
 <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
 <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
Message-ID: <08589da7-f436-e1bf-f1c4-21dfcd607736@thomas-guettler.de>



Am 08.08.2017 um 12:56 schrieb Chris Warrick:
> On 8 August 2017 at 03:30, Ben Finney <ben+python at benfinney.id.au> wrote:
>> Thomas G?ttler <guettliml at thomas-guettler.de> writes:
>>
>>> Why is "the sane default is 'use console_scripts entry-point in
>>> setup.py'" not a good answer?
>>
>> Because third-party Setuptools is required for entry points, which means
>> entry points cannot be a default choice.
>>
>> It may well be a good choice for many cases. But that's a different
>> matter from it being a good *default* choice; it can only be a default
>> choice if it's in the standard library.
> 
> While setuptools is not officially part of the stdlib, it *is*
> recommended by the official documentation, the dev team, and it?s
> available pretty much everywhere. setuptools can?t be in stdlib,
> because it?s moving too fast for stdlib to keep up.
> 
> Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on
> PyPI use wheels. It means that at least that many use setuptools;
> sometimes with a distutils fallback, but often without one. Moreover,
> many of the packages without wheels use setuptools as well.
> 



> The sane default choice is entry_points.

Sounds good. Thank you for this statement.

Regards,
   Thomas G?ttler




-- 
Thomas Guettler http://www.thomas-guettler.de/

From jm77tmp at gmail.com  Wed Aug  9 11:37:31 2017
From: jm77tmp at gmail.com (Jaroslaw Michalski)
Date: Wed, 9 Aug 2017 16:37:31 +0100
Subject: [Tutor] Tutor Digest, Vol 162, Issue 25
In-Reply-To: <mailman.103.1502249785.2822.tutor@python.org>
References: <mailman.103.1502249785.2822.tutor@python.org>
Message-ID: <CALOn5ndyhiRcDzeiJq2FY2hND43QGfyMROOVKfVkVp5xkvM66g@mail.gmail.com>

>
> > The machine I'm on here is writing big endian UTF-16 and UTF-32.
> >
> > As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
> > is because each encoding has a leading byte order marker to indicate the big
> > endianness or little endianness. For big endian data that is \xff\xfe; for
> > little endian data it would be \xfe\xff.
>
> The arithmetic as I mentioned in my original post is what I am
> expecting in "bytes", but my current thinking is that if I have for
> the BOM you point out "\xff\xfe", I translate that as 4 hex digits,
> each having 16 bits, for a total of 64 bits or 8 bytes.  What am I
> misunderstanding here?  Is a definition of "byte" meaning something
> other than 8 bits here?  I vaguely recall reading somewhere that
> "byte" can mean different numbers of bits in different contexts.
>
> And is len() actually counting "bytes" or something else for these encodings
>

Hi there.
"\xff\xfe" it looks like 4 hex digits, but 1 hex digit can be
represented by only 4 binary digits.
1 byte is 8 bits, so 2 hex digits per 1 byte
xff is one byte and you've got 2 hex digits.
xf (as a hex digit) can be represented as b1111 (binary format)
xff\xfe in a binary format is b1111 1111 \ b1111 1110
4 hex digits = 16 bits = 2 bytes
for example xff is b11111111 = 255 and it's the biggest number when
you use only 8 bits (1byte)
The problem was that 16 bits per a hex digit is not true. One hex
digit is only 4 bits, from b0000 or x0 to b1111 or xf (dec 15)
I hope it's clear now.

From tmrsg11 at gmail.com  Wed Aug  9 12:06:37 2017
From: tmrsg11 at gmail.com (C W)
Date: Wed, 9 Aug 2017 12:06:37 -0400
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
Message-ID: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>

Dear Python experts,

What exactly does the three dots do?
> aList = ...
> type(pList)
ellipsis

It's an ellipsis, a spot holder to later. But what data type is it: vector,
matrix?

In every other language, you initialize a variable you want to use. What's
the point of ellipsis?

Thanks!

From steve at pearwood.info  Wed Aug  9 17:15:26 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 10 Aug 2017 07:15:26 +1000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
References: <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
 <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
Message-ID: <20170809211526.GB7395@ando.pearwood.info>

On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote:

> While setuptools is not officially part of the stdlib,

This is the critical factor. How can you use *by default* something that 
is *NOT* supplied by default?

Obviously you cannot. It is physically impossible.


> it *is*
> recommended by the official documentation, the dev team, and it?s
> available pretty much everywhere.

Maybe if your concept of "everywhere" is limited to the subset of Python 
users who have a Linux distro and the permission (both the computer 
privileges and the legal authority) to install software on the computer 
they are using.

But this does NOT hold for everyone, possibly not even for the majority 
of Python users. For example: 

- students using their school's computers;

- corporate and government users using a SOE (Standard Operating
  Environment);

- people using a system where, for policy reasons, only the 
  standard library is permitted.

(E.g. they have their software audited for compliance with licencing and 
malware, the std lib has been audited but third party libraries have 
not. It might take literally months to get permission to install even a 
simple third party library.)

I've worked in places where installing unauthorized software was a 
firing offence.


> setuptools can?t be in stdlib,
> because it?s moving too fast for stdlib to keep up.

The reason doesn't matter. What matters is that it isn't available by 
default, so it cannot be the default.


> Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on
> PyPI use wheels. It means that at least that many use setuptools;
> sometimes with a distutils fallback, but often without one. Moreover,
> many of the packages without wheels use setuptools as well.

All this tells me is that many third party packages choose the 
*convenient* choice, not the *default* choice.

That is their right, of course. Nobody says otherwise.

And of course the sort of users who cannot install setuptools likewise 
cannot install their package, so the developers might not care about 
people without setuptools. But that hardly makes it the *default*. It 
just makes it the more popular option.


> The sane default choice is entry_points.

Only if your definition of "sane" or "default" is different from mine.



-- 
Steve

From tmrsg11 at gmail.com  Wed Aug  9 18:51:16 2017
From: tmrsg11 at gmail.com (C W)
Date: Wed, 9 Aug 2017 18:51:16 -0400
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
In-Reply-To: <CAE2FW2mspyHLovh3FwMUWCO5JBSdsJDGrDU9_ZmSSBJX3NWafA@mail.gmail.com>
References: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
 <oltbcu$1is$1@blaine.gmane.org>
 <CAE2FW2mspyHLovh3FwMUWCO5JBSdsJDGrDU9_ZmSSBJX3NWafA@mail.gmail.com>
Message-ID: <CAE2FW2ntcMO3WKATa0tQngVGsEovQNCjRjgzXozmNMSyYAV_zw@mail.gmail.com>

This is a follow up. I actually ran into this today:

import numpy as np
xArray = np.ones((3, 4))

> xArray.shape
(3, 4)
> np.shape(xArray)
(3, 4)

It was confusing to see that both xArray.shape and np.shape() worked. Are
they equivalent?

In the case of sort() vs sorted(), they are different, but close enough to
mistake them as the same thing.

Thanks!

On Wed, Aug 2, 2017 at 9:32 PM, C W <tmrsg11 at gmail.com> wrote:

> As pointed out by someone else, ?sorted
> sorted(iterable, key=None, reverse=False)
>
> It seems like the only requirement is iterable. I guess tuple is iterable,
> so, it doesn't break the assumption that tuple is immutable.
>
> That's what I see, am I right in that?
>
> Thanks!
>
> On Wed, Aug 2, 2017 at 4:07 PM, Alan Gauld via Tutor <tutor at python.org>
> wrote:
>
>> On 02/08/17 20:01, C W wrote:
>>
>> > I am a little confused about why Tuple can be sorted.
>> >
>> > Suppose I have the following,
>> >
>> >> aTuple = (9, 3, 7, 5)
>> >> sorted(aTuple)
>> > [3, 5, 7, 9]
>>
>> sorted() returns a new object.
>> The original tuple has not been changed
>>  - print aTuple to confirm this.
>>
>> HTH
>> --
>> 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
>>
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
>>
>
>

From alan.gauld at yahoo.co.uk  Wed Aug  9 19:32:16 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 10 Aug 2017 00:32:16 +0100
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <20170809211526.GB7395@ando.pearwood.info>
References: <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
 <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
 <20170809211526.GB7395@ando.pearwood.info>
Message-ID: <omg61p$spl$1@blaine.gmane.org>

On 09/08/17 22:15, Steven D'Aprano wrote:
> On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote:
> 
>> While setuptools is not officially part of the stdlib,
> 
> This is the critical factor. How can you use *by default* something that 
> is *NOT* supplied by default?

I have to agree with Steven here. Any mature language should
ship with all the tools needed to create and distribute a
finished program. It is to Python's shame that it currently
fails that test because the recommended distribution framework
is not part of the standard language package. (and the irony
is that the tool for installing the recommended format (pip)
is in the standard library. You can download other peoples
stuff but you can't make your own in the same format.
That's bad.

I hope that this is remedied soon, but for the moment Python
is horribly at odds with itself - enough to disqualify it
from use in many organisations.

Any default solution must be available by default.
It doesn't matter how many people recommend another
solution, if it isn't there it can't be used, and
therefore, can't be the default.

Sadly there seem to be many in the Python community who
do not understand the seriousness of this limitation
in terms of Python's adoption. Because they can access
it they assume everyone can. It's not true, and the further
up the Fortune 500 tree you climb the more that is the case.

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



From ben+python at benfinney.id.au  Wed Aug  9 20:33:06 2017
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 10 Aug 2017 10:33:06 +1000
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
Message-ID: <85o9rojm7x.fsf@benfinney.id.au>

C W <tmrsg11 at gmail.com> writes:

> Dear Python experts,
>
> What exactly does the three dots do?

As you've summarised: they specify a literal ellipsis object.

> It's an ellipsis, a spot holder to later. But what data type is it:
> vector, matrix?

I'm not sure what form you want the answer to take.

The most obvious form is: find out by asking Python what the type is.

    >>> type(...)
    ellipsis

So, that's what type it is.

> In every other language, you initialize a variable you want to use.

Python does not have variables like that; I think it's a mistake to
re-use the term ?variable? because it has that baggage.

Instead, what Python has are references to objects.

Some of those references are names. (Others examples are the references
that comprise a collection of objects.)

References *never* know the type of the object, and never need to be
initialised.

For a great comprehensive discussion, see Ned Batchelder's presentation
<URL:https://nedbatchelder.com/text/names.html> that will hopefully
dispel myths about Python names and objects.

> What's the point of ellipsis?

Similar to Python's type annotations, there is no rigid definition: it
is a lexical feature that allows implementations to choose their own
meaning.

The third-party NumPy assigns meaning to an ellipsis; you can learn
about the array slicing features of NumPy if you care to. If not, just
know that there is a point to it :-)

-- 
 \     ?Pinky, are you pondering what I'm pondering?? ?I think so, but |
  `\          where will we find an open tattoo parlor at this time of |
_o__)                                   night?? ?_Pinky and The Brain_ |
Ben Finney


From eryksun at gmail.com  Wed Aug  9 23:32:05 2017
From: eryksun at gmail.com (eryk sun)
Date: Thu, 10 Aug 2017 03:32:05 +0000
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <omg61p$spl$1@blaine.gmane.org>
References: <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
 <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
 <20170809211526.GB7395@ando.pearwood.info> <omg61p$spl$1@blaine.gmane.org>
Message-ID: <CACL+1asv5EctuaFBpH2jb8btoTmQW7fXmm6RM9aRY=WbTPdOJw@mail.gmail.com>

On Wed, Aug 9, 2017 at 11:32 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 09/08/17 22:15, Steven D'Aprano wrote:
>>
>> This is the critical factor. How can you use *by default* something that
>> is *NOT* supplied by default?
>
> I have to agree with Steven here. Any mature language should
> ship with all the tools needed to create and distribute a
> finished program. It is to Python's shame that it currently
> fails that test because the recommended distribution framework
> is not part of the standard language package. (and the irony
> is that the tool for installing the recommended format (pip)
> is in the standard library. You can download other peoples
> stuff but you can't make your own in the same format.
> That's bad.

The standard library has ensurepip [1] to bootstrap bundled wheels for
pip and setuptools, which in turn vendor other packages such as
distlib. The wheels are already there, unless the distro or IT
department has removed them. (They're distributed with the official
Windows installers, at least.) If you want the legal details, you
could ask on the pypa-dev list [2]. I'm sure Nick Coghlan or Donald
Stufft would be happy to clarify the situation.

[1]: https://github.com/python/cpython/tree/v3.6.2/Lib/ensurepip
[2]: https://groups.google.com/forum/#!forum/pypa-dev

From __peter__ at web.de  Thu Aug 10 02:56:44 2017
From: __peter__ at web.de (Peter Otten)
Date: Thu, 10 Aug 2017 08:56:44 +0200
Subject: [Tutor] If tuple cannot be sorted,
 then why sorted() on a tuple is fine?
References: <CAE2FW2kzMH1+foXNuyKdbAxmDg-m3v6KgRG9TZfDDrr0+cd-Pw@mail.gmail.com>
 <oltbcu$1is$1@blaine.gmane.org>
 <CAE2FW2mspyHLovh3FwMUWCO5JBSdsJDGrDU9_ZmSSBJX3NWafA@mail.gmail.com>
 <CAE2FW2ntcMO3WKATa0tQngVGsEovQNCjRjgzXozmNMSyYAV_zw@mail.gmail.com>
Message-ID: <omh036$n75$1@blaine.gmane.org>

C W wrote:

> This is a follow up. I actually ran into this today:
> 
> import numpy as np
> xArray = np.ones((3, 4))
> 
>> xArray.shape
> (3, 4)
>> np.shape(xArray)
> (3, 4)
> 
> It was confusing to see that both xArray.shape and np.shape() worked. Are
> they equivalent?

>>> print(inspect.getsource(numpy.shape))
def shape(a):
    """
    Return the shape of an array.

    Parameters
    ----------
    a : array_like
        Input array.

    Returns
    -------
    shape : tuple of ints
        The elements of the shape tuple give the lengths of the
        corresponding array dimensions.

    See Also
    --------
    alen
    ndarray.shape : Equivalent array method.

    Examples
    --------
    >>> np.shape(np.eye(3))
    (3, 3)
    >>> np.shape([[1, 2]])
    (1, 2)
    >>> np.shape([0])
    (1,)
    >>> np.shape(0)
    ()

    >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
    >>> np.shape(a)
    (2,)
    >>> a.shape
    (2,)

    """
    try:
        result = a.shape
    except AttributeError:
        result = asarray(a).shape
    return result

So no; numpy.shape() tries to convert unshapely objects to an array ;)


From kwpolska at gmail.com  Thu Aug 10 06:01:09 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Thu, 10 Aug 2017 12:01:09 +0200
Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if
 __name__=='main' vs entry points: What to teach new comers?
In-Reply-To: <20170809211526.GB7395@ando.pearwood.info>
References: <85k22mp23c.fsf@benfinney.id.au>
 <20170802145741.GN3149@ando.pearwood.info>
 <b57faf33-5bbb-ec1b-8f8c-71154fcf4718@biologie.uni-freiburg.de>
 <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de>
 <85a83gp354.fsf@benfinney.id.au>
 <a4090a93-4206-2c0f-63ca-bea44fc9d824@thomas-guettler.de>
 <85tw1modme.fsf@benfinney.id.au>
 <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de>
 <85efsmn8vn.fsf@benfinney.id.au>
 <CAMw+j7JS_KLobAL7-jqWh_9B6zL9a7zFsr8ZkW=pVD6f9r9AEw@mail.gmail.com>
 <20170809211526.GB7395@ando.pearwood.info>
Message-ID: <CAMw+j7LtdfgVudewoG0qvbAvgBkgaAzFHbM0K9RgLMDa8qeJwg@mail.gmail.com>

On 9 August 2017 at 23:15, Steven D'Aprano <steve at pearwood.info> wrote:
> On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote:
>
>> While setuptools is not officially part of the stdlib,
>
> This is the critical factor. How can you use *by default* something that
> is *NOT* supplied by default?
>
> Obviously you cannot. It is physically impossible.


The problem with setuptools (and pip) is that they are not first-party
stdlib members, but they are not third-party packages either. They?re
somewhere in between. They have been blessed by the core developers.
And yes, setuptools might be in all the places you mentioned:

> But this does NOT hold for everyone, possibly not even for the majority
> of Python users. For example:
>
> - students using their school's computers;
>
> - corporate and government users using a SOE (Standard Operating
>   Environment);
>
> - people using a system where, for policy reasons, only the
>   standard library is permitted.

* If those computers run Windows (as they often do) and run a recent
Python version (3.4 or newer/2.7.9 or newer), setuptools will be
installed, unless the IT people explicitly disabled ensurepip.
* On macOS, setuptools will be installed if they?re using the system
Python, the python.org installers (which are not uninstallable), or
Python from Homebrew. The last two also have pip, and system Python
has ensurepip.
* On Linux, setuptools/pip is likely to be there, but it?s not
required in all distributions. (Fedora mandates setuptools; Debian
even rips out ensurepip by default and hides it in python3-venv
because reasons?)

If the users are meant to install Python packages, their system
administrators would take care of that ? either by setting up
setuptools/pip and perhaps virtualenv, or taking install requests from
users. If users are not supposed to be running setuptools/pip, they
probably shouldn?t, but they can still install it from ensurepip or
downloading get-pip.py.

> I've worked in places where installing unauthorized software was a
> firing offence.

Those people don?t need setuptools. Those people should not be using
distutils either. They might not even be allowed to download packages
and run __main__.py without installation.

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From steve at pearwood.info  Thu Aug 10 08:47:59 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 10 Aug 2017 22:47:59 +1000
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
Message-ID: <20170810124759.GC7395@ando.pearwood.info>

On Wed, Aug 09, 2017 at 12:06:37PM -0400, C W wrote:
> Dear Python experts,
> 
> What exactly does the three dots do?
> > aList = ...

... is literal syntax for the Ellipsis singleton object.

Ellipsis was added to the language at the express request of the numpy 
developers. Although numpy is a third-party project outside of the 
standard library, it is big enough and important enough that their 
requests carry a LOT of weight with the core Python devs. Other features 
Python has that were originally added at the request of numpy include:

- extended slicing with two colons obj[a:b:c]

- the @ operator used by numpy for matrix multiplication.

I don't know what Ellipsis is used for by numpy, but now it makes a 
convenient pseudo-pass command:

class X:
    ...

def func():
    ...


> It's an ellipsis, a spot holder to later. But what data type is it: vector,
> matrix?

Its a singleton object. Think of it as a sibling to None and 
NotImplemented, but with optional funny syntactic sugar ... to refer to 
it.

None is a special value used as "no such value", or nil or null;

NotImplemented is a special value used by operator dunder methods like 
__add__ and __mul__ to mean "I can't handle this argument";

Ellipsis is a special value used by numpy to mean whatever it is that 
numpy uses it to me.


-- 
Steve

From steve at pearwood.info  Thu Aug 10 09:01:18 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 10 Aug 2017 23:01:18 +1000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
Message-ID: <20170810130117.GD7395@ando.pearwood.info>

On Mon, Aug 07, 2017 at 10:04:21PM -0500, Zachary Ware wrote:

> Next, take a dive into the wonderful* world of Unicode:
> 
> https://nedbatchelder.com/text/unipain.html
> https://www.youtube.com/watch?v=7m5JA3XaZ4k

Another **Must Read** resource for unicode is:

The Absolute Minimum Every Software Developer Absolutely Positively Must 
Know About Unicode (No Excuses!)

https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

(By the way, it is nearly 14 years later, and PHP still believes that 
the world is ASCII.)


Python 3 makes Unicode about as easy as it can get. To include a unicode 
string in your source code, you just need to ensure your editor saves 
the file as UTF-8, and then insert (by whatever input technology you 
have) the character you want. You want a Greek pi?

pi = "?"

How about an Israeli sheqel?

money = "?1000"

So long as your editor knows to save the file in UTF-8, it will Just 
Work.


-- 
Steve

From steve at pearwood.info  Thu Aug 10 11:13:52 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 11 Aug 2017 01:13:52 +1000
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
Message-ID: <20170810151351.GG7395@ando.pearwood.info>

On Thu, Aug 10, 2017 at 09:39:02AM -0400, C W wrote:

> What's a literal? The only other time I heard about it was studying
> Shakespare. ;)

A "literal" is syntax that creates a value, without the programmer 
needing to call a function. The syntax stands for the LITERAL value as 
shown.

For example, we write:

    number = 123  # stands for literally 123

rather than:

    number = int(hundreds=1, tens=2, units=3)

Examples of literals:

"Hello World!"  # a string
1.234  # a float
999  # an int
True  # bool true value
None  # the special None value


Technically, these aren't literals, but they're the moral equivalent of 
literals:

[1, 2, None, "Hello", 23]  # a list
(1, 2, 3)  # a tuple
{'key': 'value'}  # a dict


> I don't know what literal is. So, it won't help me to understand ellipsis,
> I really thought it was that oval shaped figure.

Ellipsis \El*lip"sis\ ([e^]l*l[i^]p"s[i^]s), n.; pl. Ellipses

      (Gram.) Omission; a figure of syntax, by which one or more
      words, which are obviously understood, are omitted; as,
      the virtues I admire, for, the virtues which I admire.
      [1913 Webster]

      (Printing) a printing symbol, usually three periods in a
      row (. . .), indicating the omission of some part of a
      text; -- used commonly in quotations, so as to suppress
      words not essential to the meaning. A long dash (---) and
      three asterisks (* * *) are sometimes used with the same
      meaning.


There's also an older (now obsolete) meaning of "ellipsis" as a synonym 
for "ellipse", which is an oval-shaped figure.


> Wiki says: "Literals are often used to initialize variables"

As in:

n = 0
x = 1.5



Outside of numpy, I've never seen anyone use Ellipsis (whether spelled 
by name or by three dots) except to be cute. I'm sure it has use to some 
people, otherwise it wouldn't have been added, but its pretty 
specialized.




-- 
Steve

From tmrsg11 at gmail.com  Thu Aug 10 09:39:02 2017
From: tmrsg11 at gmail.com (C W)
Date: Thu, 10 Aug 2017 09:39:02 -0400
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <20170810124759.GC7395@ando.pearwood.info>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
Message-ID: <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>

What's a literal? The only other time I heard about it was studying
Shakespare. ;)

I don't know what literal is. So, it won't help me to understand ellipsis,
I really thought it was that oval shaped figure.

Wiki says: "Literals are often used to initialize variables"

https://en.wikipedia.org/wiki/Literal_(computer_programming)

I suppose it's just a place holder, though I don't know when I would use it
in my every day life.

On Thu, Aug 10, 2017 at 8:47 AM, Steven D'Aprano <steve at pearwood.info>
wrote:

> On Wed, Aug 09, 2017 at 12:06:37PM -0400, C W wrote:
> > Dear Python experts,
> >
> > What exactly does the three dots do?
> > > aList = ...
>
> ... is literal syntax for the Ellipsis singleton object.
>
> Ellipsis was added to the language at the express request of the numpy
> developers. Although numpy is a third-party project outside of the
> standard library, it is big enough and important enough that their
> requests carry a LOT of weight with the core Python devs. Other features
> Python has that were originally added at the request of numpy include:
>
> - extended slicing with two colons obj[a:b:c]
>
> - the @ operator used by numpy for matrix multiplication.
>
> I don't know what Ellipsis is used for by numpy, but now it makes a
> convenient pseudo-pass command:
>
> class X:
>     ...
>
> def func():
>     ...
>
>
> > It's an ellipsis, a spot holder to later. But what data type is it:
> vector,
> > matrix?
>
> Its a singleton object. Think of it as a sibling to None and
> NotImplemented, but with optional funny syntactic sugar ... to refer to
> it.
>
> None is a special value used as "no such value", or nil or null;
>
> NotImplemented is a special value used by operator dunder methods like
> __add__ and __mul__ to mean "I can't handle this argument";
>
> Ellipsis is a special value used by numpy to mean whatever it is that
> numpy uses it to me.
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From alan.gauld at yahoo.co.uk  Thu Aug 10 19:23:46 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 11 Aug 2017 00:23:46 +0100
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
Message-ID: <omiptr$mg2$1@blaine.gmane.org>

On 10/08/17 14:39, C W wrote:

> I suppose it's just a place holder, though I don't know when I would use it
> in my every day life.

Probably never.

Like most programming languages Python has a load of rarely used,
obscure features. Most Python programmers never use ellipses,
metaclasses(*), the __new__() constructor, the _ variable or
even the else clause in a loop. That doesn't mean you shouldn't
look into them - they might just be the bit of magic you
need - but don't feel you need to have a use for every
bit of the language.

(*) Actually, everyone uses metaclasses, but very few define
their own!

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



From robertvstepp at gmail.com  Thu Aug 10 21:40:05 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 10 Aug 2017 20:40:05 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <20170810130117.GD7395@ando.pearwood.info>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
 <20170810130117.GD7395@ando.pearwood.info>
Message-ID: <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>

On Thu, Aug 10, 2017 at 8:01 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>
> Another **Must Read** resource for unicode is:
>
> The Absolute Minimum Every Software Developer Absolutely Positively Must
> Know About Unicode (No Excuses!)
>
> https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

This was an enjoyable read, but did not have as much technical detail
as the two videos Zach had referenced.  But then the author did say
"the absolute minimum ...".  I will strive to avoid peeling onions on
a sub!

> (By the way, it is nearly 14 years later, and PHP still believes that
> the world is ASCII.)

I thought you must surely be engaging in hyperbole, but at
http://php.net/manual/en/xml.encoding.php I found:

"The default source encoding used by PHP is ISO-8859-1."

>
> Python 3 makes Unicode about as easy as it can get. To include a unicode
> string in your source code, you just need to ensure your editor saves
> the file as UTF-8, and then insert (by whatever input technology you
> have) the character you want. You want a Greek pi?
>
> pi = "?"
>
> How about an Israeli sheqel?
>
> money = "?1000"
>
> So long as your editor knows to save the file in UTF-8, it will Just
> Work.

So Python 3's default behavior for strings is to store them as UTF-8
encodings in both RAM and files?  No funny business anywhere?  Except
perhaps in my Windows 7 cmd.exe and PowerShell, but that's not
Python's fault.  Which makes me wonder, what is my editor's default
encoding/decoding?  I will have to investigate!

Cheers!

-- 
boB

From robertvstepp at gmail.com  Thu Aug 10 21:48:42 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 10 Aug 2017 20:48:42 -0500
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>
References: <CANDiX9LUfrz=FBKM2uv9AX3GaWNgXDwRysEY5-XNyPLBLjg3_w@mail.gmail.com>
 <CAKJDb-OKUZ5fq-rxDcTODc9+yjhHnnHU3jsPOm4ShoWeopr9og@mail.gmail.com>
 <20170810130117.GD7395@ando.pearwood.info>
 <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>
Message-ID: <CANDiX9JCG2qZHPL3N_=eAtPNf0EAJP4DXmB0Wu=mqtmqEDo9FA@mail.gmail.com>

On Thu, Aug 10, 2017 at 8:40 PM, boB Stepp <robertvstepp at gmail.com> wrote:
> On Thu, Aug 10, 2017 at 8:01 AM, Steven D'Aprano <steve at pearwood.info> wrote:

>> Python 3 makes Unicode about as easy as it can get. To include a unicode
>> string in your source code, you just need to ensure your editor saves
>> the file as UTF-8, and then insert (by whatever input technology you
>> have) the character you want. You want a Greek pi?
>>
>> pi = "?"
>>
>> How about an Israeli sheqel?
>>
>> money = "?1000"
>>
>> So long as your editor knows to save the file in UTF-8, it will Just
>> Work.
>
> So Python 3's default behavior for strings is to store them as UTF-8
> encodings in both RAM and files?  No funny business anywhere?  Except
> perhaps in my Windows 7 cmd.exe and PowerShell, ...

A while back I adopted a suggestion by Eryk Sun and installed ConEmu
on my Windows 7, and now use it in place of cmd.exe.  Interestingly,
it apparently provides UTF-8 support where cmd.exe and PowerShell do
not.  I just tested it with your two examples in cmd.exe, PowerShell
and both of these shells accessed via ConEmu.  Interesting!  Thanks,
Eryk, for making me aware of this program!


-- 
boB

From cs at cskk.id.au  Thu Aug 10 22:34:06 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Fri, 11 Aug 2017 12:34:06 +1000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>
References: <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>
Message-ID: <20170811023406.GA87710@cskk.homeip.net>

On 10Aug2017 20:40, boB Stepp <robertvstepp at gmail.com> wrote:
>> (By the way, it is nearly 14 years later, and PHP still believes that
>> the world is ASCII.)
>
>I thought you must surely be engaging in hyperbole, but at
>http://php.net/manual/en/xml.encoding.php I found:
>
>"The default source encoding used by PHP is ISO-8859-1."

This kind of amounts to Python 2's situation in some ways: a PHP string or 
Python 2 str is effectively just an array of bytes, treated like a lexical 
stringy thing.

If you're working only in ASCII or _universally_ in some fixed 8-bit character 
set (eg ISO8859-1 in Western Europe) you mostly get by if you don't look 
closely. PHP's "default source encoding" means that the variable _character_ 
based routines in PHP (things that know about characters as letter, punctuation 
etc) treat these strings as using IS8859-1 encoding. You can load UTF-8 into 
these strings and work that way too (there's a PHP global setting for the 
encoding).

Python 2 has a "unicode" type for proper Unicode strings.

In Python 3 str is Unicode text, and you use bytes for bytes. It is hugely 
better, because you don't need to concern yourself about what text encoding a 
str is - it doesn't have one - it is Unicode. You only need to care when 
reading and writing data.

>> So long as your editor knows to save the file in UTF-8, it will Just
>> Work.
>
>So Python 3's default behavior for strings is to store them as UTF-8
>encodings in both RAM and files?

Not quite.

In memory Python 3 strings are sequences of Unicode code points. The CPython 
internals pick an 8 or 16 or 32 bit storage mode for these based on the highest 
code point value in the string as a space optimisation decision, but that is 
concealed at the language level. UTF-8 as a storage format is nearly as 
compact, but has the disadvantage that you can't directly index the string 
(i.e. go to character "n") because UTF-8 uses variable length encodings for the 
various code points.

In files however, the default encoding for text files is 'utf-8': Python will 
read the file's bytes as UTF-8 data and will write Python string characters in 
UTF-8 encoding when writing.

If you open a file in "binary" mode there's no encoding: you get bytes. But if 
you open in text mode (no "b" in the open mode string) you get text, and you 
can define the character encoding used as an optional parameter to the open() 
function call.

>No funny business anywhere?  Except
>perhaps in my Windows 7 cmd.exe and PowerShell, but that's not
>Python's fault.  Which makes me wonder, what is my editor's default
>encoding/decoding?  I will have to investigate!

On most UNIX platforms most situations expect and use UTF-8. There aresome 
complications because this needn't be the case, but most modern environments 
provide UTF-8 by default.

The situation in Windows is more complex for historic reasons. I believe Eryk 
Sun is the go to guy for precise technical descriptions of the Windows 
situation. I'm not a Windows guy, but I gather modern Windows generally gives 
you a pretty clean UTF-8 environment in most situations.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From eryksun at gmail.com  Thu Aug 10 23:27:50 2017
From: eryksun at gmail.com (eryk sun)
Date: Fri, 11 Aug 2017 03:27:50 +0000
Subject: [Tutor] How does len() compute length of a string in UTF-8, 16,
 and 32?
In-Reply-To: <20170811023406.GA87710@cskk.homeip.net>
References: <CANDiX9KiSQGrpv0dAo-AZ0Ee-z-cfFweRjWD=V9fpC3ah9p8zw@mail.gmail.com>
 <20170811023406.GA87710@cskk.homeip.net>
Message-ID: <CACL+1avE6Kc6Log2+08Bh6hGdf1-HtMMXoA03Vwj+4CFaSbeXw@mail.gmail.com>

On Fri, Aug 11, 2017 at 2:34 AM, Cameron Simpson <cs at cskk.id.au> wrote:
>
> In files however, the default encoding for text files is 'utf-8': Python
> will read the file's bytes as UTF-8 data and will write Python string
> characters in UTF-8 encoding when writing.

The default encoding for source files is UTF-8. The default encoding
for text files is the locale's preferred encoding, i.e.
locale.getpreferredencoding(False). On Windows this is the locale's
ANSI codepage (e.g. 1252 in Western Europe). Also, the default newline
string in text files is os.linesep. On Windows this is "\r\n".

From mats at wichmann.us  Fri Aug 11 09:57:09 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 11 Aug 2017 07:57:09 -0600
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <omiptr$mg2$1@blaine.gmane.org>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
 <omiptr$mg2$1@blaine.gmane.org>
Message-ID: <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>

On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote:
> On 10/08/17 14:39, C W wrote:
> 
>> I suppose it's just a place holder, though I don't know when I would use it
>> in my every day life.
> 
> Probably never.
> 
> Like most programming languages Python has a load of rarely used,
> obscure features. Most Python programmers never use ellipses,

I guess what this means is when I post code snippets with some lines
elided for greater readability of the point being made I should not use
ellipses for that, as they're actually a syntactic element!   :)


From guettliml at thomas-guettler.de  Fri Aug 11 08:35:00 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Fri, 11 Aug 2017 14:35:00 +0200
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
Message-ID: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>

I start a new thread, since this is a new topic.

I don't have the deep knowledge like Chris, Steven or Alan.

I guess most python installations have setuptools. But this is only my naive vague guess.

How high is the percentage of python installation which don't have setuptools?

I have no clue. Is it 5%, 10%, 15% ...?

I know there is no definite answer to this question. But you can guess this better than me.

Regards,
  Thomas G?ttler



Am 10.08.2017 um 12:01 schrieb Chris Warrick:
 > On 9 August 2017 at 23:15, Steven D'Aprano <steve at pearwood.info> wrote:
 >> On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote:
 >>
 >>> While setuptools is not officially part of the stdlib,
 >>
 >> This is the critical factor. How can you use *by default* something that
 >> is *NOT* supplied by default?
 >>
 >> Obviously you cannot. It is physically impossible.
 >
 >
 > The problem with setuptools (and pip) is that they are not first-party
 > stdlib members, but they are not third-party packages either. They?re
 > somewhere in between. They have been blessed by the core developers.
 > And yes, setuptools might be in all the places you mentioned:
 >
 >> But this does NOT hold for everyone, possibly not even for the majority
 >> of Python users. For example:
 >>
 >> - students using their school's computers;
 >>
 >> - corporate and government users using a SOE (Standard Operating
 >>    Environment);
 >>
 >> - people using a system where, for policy reasons, only the
 >>    standard library is permitted.
 >
 > * If those computers run Windows (as they often do) and run a recent
 > Python version (3.4 or newer/2.7.9 or newer), setuptools will be
 > installed, unless the IT people explicitly disabled ensurepip.
 > * On macOS, setuptools will be installed if they?re using the system
 > Python, the python.org installers (which are not uninstallable), or
 > Python from Homebrew. The last two also have pip, and system Python
 > has ensurepip.
 > * On Linux, setuptools/pip is likely to be there, but it?s not
 > required in all distributions. (Fedora mandates setuptools; Debian
 > even rips out ensurepip by default and hides it in python3-venv
 > because reasons?)
 >
 > If the users are meant to install Python packages, their system
 > administrators would take care of that ? either by setting up
 > setuptools/pip and perhaps virtualenv, or taking install requests from
 > users. If users are not supposed to be running setuptools/pip, they
 > probably shouldn?t, but they can still install it from ensurepip or
 > downloading get-pip.py.
 >
 >> I've worked in places where installing unauthorized software was a
 >> firing offence.
 >
 > Those people don?t need setuptools. Those people should not be using
 > distutils either. They might not even be allowed to download packages
 > and run __main__.py without installation.
 >
-- 
Thomas Guettler http://www.thomas-guettler.de/


-- 
Thomas Guettler http://www.thomas-guettler.de/

From alan.gauld at yahoo.co.uk  Fri Aug 11 11:38:57 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 11 Aug 2017 16:38:57 +0100
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
 <omiptr$mg2$1@blaine.gmane.org>
 <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>
Message-ID: <omkj2a$ddk$1@blaine.gmane.org>

On 11/08/17 14:57, Mats Wichmann wrote:

>> obscure features. Most Python programmers never use ellipses,
> 
> I guess what this means is when I post code snippets with some lines
> elided for greater readability of the point being made I should not use
> ellipses for that, as they're actually a syntactic element!   :)

Good point, because I often do that when replying to posts

def foo():...

I certainly don't mean the ellipses to be a syntactic element!


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



From alan.gauld at yahoo.co.uk  Fri Aug 11 11:54:49 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 11 Aug 2017 16:54:49 +0100
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
Message-ID: <omkk02$eda$1@blaine.gmane.org>

On 11/08/17 13:35, Thomas G?ttler wrote:

> I guess most python installations have setuptools. 

I guess so too, although I don't know.
Those that don't are probably in one of two categories
a) people who just downloaded Python and never installed
   anything else
b) people working for large paranoid corporates. Although
   in this case there is probably only one installation,
   albeit with hundreds of users.

So far as I can tell I don't have it on any of my
Python installs on my Linux box, but I may just be looking
in the wrong place... I know I have it on my Windows box.

> But this is only my naive vague guess.

Me too :-)

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



From mats at wichmann.us  Fri Aug 11 13:54:06 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 11 Aug 2017 11:54:06 -0600
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <omkk02$eda$1@blaine.gmane.org>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
 <omkk02$eda$1@blaine.gmane.org>
Message-ID: <f3a7add5-4235-e35c-dfe7-62a9c2b98d44@wichmann.us>

On 08/11/2017 09:54 AM, Alan Gauld via Tutor wrote:
> On 11/08/17 13:35, Thomas G?ttler wrote:
> 
>> I guess most python installations have setuptools. 
> 
> I guess so too, although I don't know.
> Those that don't are probably in one of two categories
> a) people who just downloaded Python and never installed
>    anything else
> b) people working for large paranoid corporates. Although
>    in this case there is probably only one installation,
>    albeit with hundreds of users.
> 
> So far as I can tell I don't have it on any of my
> Python installs on my Linux box, but I may just be looking
> in the wrong place... 

Most Linux distributions choose to make it a separate package.  I have
it (them - one for Py2 and one for Py3) installed everywhere, but I'd
guess it's not a default install then.

Fedora:
python2-setuptools-36.2.0-1.fc26.noarch
python3-setuptools-36.2.0-1.fc26.noarch

Ubuntu:
Desired=Unknown/Install/Remove/Purge/Hold
|
Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                  Version      Architecture Description
+++-=====================-============-============-=================================
ii  python-setuptools     33.1.1-1     all          Python Distutils
Enhancements
ii  python3-setuptools    33.1.1-1     all          Python3 Distutils
Enhancements

From kwpolska at gmail.com  Fri Aug 11 14:13:24 2017
From: kwpolska at gmail.com (Chris Warrick)
Date: Fri, 11 Aug 2017 20:13:24 +0200
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <f3a7add5-4235-e35c-dfe7-62a9c2b98d44@wichmann.us>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
 <omkk02$eda$1@blaine.gmane.org>
 <f3a7add5-4235-e35c-dfe7-62a9c2b98d44@wichmann.us>
Message-ID: <CAMw+j7Kh6zwcD_c7MJ829a9Xuu0XQU+FdxRyZYMdB4Y8hXYHhQ@mail.gmail.com>

On 11 August 2017 at 19:54, Mats Wichmann <mats at wichmann.us> wrote:
> On 08/11/2017 09:54 AM, Alan Gauld via Tutor wrote:
>> On 11/08/17 13:35, Thomas G?ttler wrote:
>>
>>> I guess most python installations have setuptools.
>>
>> I guess so too, although I don't know.
>> Those that don't are probably in one of two categories
>> a) people who just downloaded Python and never installed
>>    anything else

False since Python 3.4/2.7.9. ensurepip installs Python on every new
Python install.

> Most Linux distributions choose to make it a separate package.  I have
> it (them - one for Py2 and one for Py3) installed everywhere, but I'd
> guess it's not a default install then.
>
> Fedora:
> python2-setuptools-36.2.0-1.fc26.noarch
> python3-setuptools-36.2.0-1.fc26.noarch
>
> Ubuntu:
> Desired=Unknown/Install/Remove/Purge/Hold
> |
> Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
> |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
> ||/ Name                  Version      Architecture Description
> +++-=====================-============-============-=================================
> ii  python-setuptools     33.1.1-1     all          Python Distutils
> Enhancements
> ii  python3-setuptools    33.1.1-1     all          Python3 Distutils
> Enhancements

On Fedora, setuptools is mandatory:

package: python3-3.6.2-1.fc26.x86_64
[snip some unrelated stuff]
  dependency: python3-pip
   provider: python3-pip-9.0.1-9.fc26.noarch
  dependency: python3-setuptools
   provider: python3-setuptools-36.2.0-1.fc26.noarch

On other distributions, it usually isn?t, although many users will
eventually end up with a copy.

-- 
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16

From alan.gauld at yahoo.co.uk  Fri Aug 11 14:27:11 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 11 Aug 2017 19:27:11 +0100
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <CAMw+j7Kh6zwcD_c7MJ829a9Xuu0XQU+FdxRyZYMdB4Y8hXYHhQ@mail.gmail.com>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
 <omkk02$eda$1@blaine.gmane.org>
 <f3a7add5-4235-e35c-dfe7-62a9c2b98d44@wichmann.us>
 <CAMw+j7Kh6zwcD_c7MJ829a9Xuu0XQU+FdxRyZYMdB4Y8hXYHhQ@mail.gmail.com>
Message-ID: <omksto$h5u$1@blaine.gmane.org>

On 11/08/17 19:13, Chris Warrick wrote:

>>> a) people who just downloaded Python and never installed
>>>    anything else
> 
> False since Python 3.4/2.7.9. ensurepip installs Python on every new
> Python install.

Sorry Chris, that's not making sense? Do you mean ensurepip
installs setuptools on every install? How does it do that if
I don't have the internet connected? Does it wait for
a connection then automatically do a download?

How would I tell if it is installed? Where do I look and
for what? Because its not where I thought it would be
- (in the libs)...

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



From eryksun at gmail.com  Fri Aug 11 15:00:27 2017
From: eryksun at gmail.com (eryk sun)
Date: Fri, 11 Aug 2017 19:00:27 +0000
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <omksto$h5u$1@blaine.gmane.org>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
 <omkk02$eda$1@blaine.gmane.org>
 <f3a7add5-4235-e35c-dfe7-62a9c2b98d44@wichmann.us>
 <CAMw+j7Kh6zwcD_c7MJ829a9Xuu0XQU+FdxRyZYMdB4Y8hXYHhQ@mail.gmail.com>
 <omksto$h5u$1@blaine.gmane.org>
Message-ID: <CACL+1auYroKLEcA3qSYtwHoMasAbcpVrj7Jng4wuH-qajDtH_w@mail.gmail.com>

On Fri, Aug 11, 2017 at 6:27 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 11/08/17 19:13, Chris Warrick wrote:
>
>> False since Python 3.4/2.7.9. ensurepip installs Python on every new
>> Python install.
>
> Sorry Chris, that's not making sense? Do you mean ensurepip
> installs setuptools on every install? How does it do that if
> I don't have the internet connected? Does it wait for
> a connection then automatically do a download?

The Windows installer defaults to running ensurepip, which bundles
wheels for pip and setuptools. They may not be the latest versions.

> How would I tell if it is installed? Where do I look and
> for what? Because its not where I thought it would be
> - (in the libs)...

On Windows, look in "Lib\site-packages". In general you can `import
pip` and check pip.__file__. You should also have pip and pip3
commands. Run `pip3 show pip` to check the location.

From steve at pearwood.info  Fri Aug 11 21:24:05 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 12 Aug 2017 11:24:05 +1000
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
 <omiptr$mg2$1@blaine.gmane.org>
 <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>
Message-ID: <20170812012405.GL7395@ando.pearwood.info>

On Fri, Aug 11, 2017 at 07:57:09AM -0600, Mats Wichmann wrote:
> On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote:
> > On 10/08/17 14:39, C W wrote:
> > 
> >> I suppose it's just a place holder, though I don't know when I would use it
> >> in my every day life.
> > 
> > Probably never.
> > 
> > Like most programming languages Python has a load of rarely used,
> > obscure features. Most Python programmers never use ellipses,
> 
> I guess what this means is when I post code snippets with some lines
> elided for greater readability of the point being made I should not use
> ellipses for that, as they're actually a syntactic element!   :)

No, go right ahead and continue using ... for elided lines. Python 3 
makes that syntactically legal, and the fact that elided code may be 
syntactically correct is one of the reasons that was done.

In Python 2, ... was just the *display* form of Ellipsis, and wasn't 
legal except in slice notation: a[...]. Python 3 made ... syntactic 
sugar for Ellipse everywhere, not just in slices, which makes:

    x = ...

    class X:
        ...

perfectly legal code. (Perhaps not *meaningful* code, but that's okay.)


-- 
Steve

From bandagunda at hotmail.com  Fri Aug 11 11:10:27 2017
From: bandagunda at hotmail.com (banda gunda)
Date: Fri, 11 Aug 2017 15:10:27 +0000
Subject: [Tutor] conditional renaming folder and files in the tree
In-Reply-To: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>
References: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>
Message-ID: <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>

Dear Tutor,

I want to change the name of the folders and the files in the tree.
All those folders and files starting with name string '---'.
Examples:
If a  folder name is : \---DAT1
I want to change this to: \changedDAT1
If a file name is: \---00001.txt
I want to change this to: \changed00001.txt

I have attached the code and output to this email.
Specifically, I like to provide correct syntax (dst / destination) for line 6 code block below!
I have not understood the syntax.

Thanks in advance, for your help .
best,
banda
+


for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        print(os.path.join(root, name))
        os.rename(name.replace("---", "changed"))
        list_of_files[name] = os.sep.join([dirpath, name])
        print (list_of_files)

    for name in dirs:
        print(os.path.join(root, name))


.\---DAT1\---00001.txt


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-b679212713d0> in <module>()
      2     for name in files:
      3         print(os.path.join(root, name))
----> 4         os.rename(name.replace("---", "changed"))
      5         list_of_files[name] = os.sep.join([dirpath, name])
      6         print (list_of_files)

TypeError: Required argument 'dst' (pos 2) not found

_end_of_email

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: file_folder_replace_name_strings.html
URL: <http://mail.python.org/pipermail/tutor/attachments/20170811/15282a5e/attachment-0001.ksh>

From alan.gauld at yahoo.co.uk  Sat Aug 12 03:51:51 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 12 Aug 2017 08:51:51 +0100
Subject: [Tutor] conditional renaming folder and files in the tree
In-Reply-To: <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
References: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>
 <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <ommc2f$3kk$1@blaine.gmane.org>

On 11/08/17 16:10, banda gunda wrote:

> for root, dirs, files in os.walk(".", topdown=False):
>     for name in files:
>         print(os.path.join(root, name))
>         os.rename(name.replace("---", "changed"))

Here you give the new name but not the original name.
The function needs two values, the source(original name)
and the destination(dst)


>         list_of_files[name] = os.sep.join([dirpath, name])

What is dirpath? This is its first mention.

> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-6-b679212713d0> in <module>()
> ----> 4         os.rename(name.replace("---", "changed"))
> 
> TypeError: Required argument 'dst' (pos 2) not found

See above

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



From steve at pearwood.info  Sat Aug 12 20:12:47 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 13 Aug 2017 10:12:47 +1000
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
Message-ID: <20170813001245.GN7395@ando.pearwood.info>

On Fri, Aug 11, 2017 at 02:35:00PM +0200, Thomas G?ttler wrote:

> How high is the percentage of python installation which don't have 
> setuptools?
> 
> I have no clue. Is it 5%, 10%, 15% ...?
> 
> I know there is no definite answer to this question. But you can guess this 
> better than me.

Somewhere between 0.1% and 99.9%.

For what little it is worth, out of the 9 versions of Python I have 
installed on my personal machines, setuptools is installed for 4 of 
them. On work machines, 2 out of 5 have setuptools installed. So in 
total, 6 out of 14 Python installations I have access to include 
setuptools. So 57% *don't* have setup tools.

Really Thomas, why do you care? If you want to require setuptools for 
your packages, go right ahead. If you want to tell people that using 
setuptools is the best choice, or the most popular choice, or the 
smartest choice, do so.

Just don't say it is the "default choice" because that is silly. The 
whole purpose of something being *default* is so that you DON'T have to 
make a choice. Obviously that doesn't apply to choosing a packaging 
library, and especially not to choosing a packaging language which may 
not even be present. Even if its only missing 1% of the time.

As a third-party author, the sorts of people who don't have setuptools 
installed either won't be installing your software at all, or will be 
installing it from source.


-- 
Steve

From robertvstepp at gmail.com  Sun Aug 13 01:22:52 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 13 Aug 2017 00:22:52 -0500
Subject: [Tutor] Long post: Request comments on starting code and test code
 on chess rating project.
Message-ID: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>

I mentioned in one of the recent threads that I started that it is
probably time for me to attempt a substantial project using the OO
paradigm.  I have had no coursework or training in OOP other than my
recent self-studies.  Everything (Other than toy practice examples.) I
have coded to date has been strictly procedural, similar to what I
learned in FORTRAN ages ago.  Also, I am continuing to try to do TDD
and keep things DRY.  So I am hoping for a thorough critique of what I
will shortly present.  Everything is fair game!  Hopefully my
self-esteem is up to this critique!

The intent of this project is more than just calculate chess ratings.
I also envision being able to store a record of all game results and
player information for my school chess players that I give lessons to.
Some functionality I will strive to include:  1) Be able to re-rate
all games from a given date to the present.  2) Record demographic
information about my players, such as names, current school year,
current grade, etc.  3) Have a very friendly GUI so that when I have a
finished project, a student could easily take over responsibility of
maintaining the school's player ratings, if I so choose to allow this.
4) Having an editor where games and player data (But NOT ratings;
these would have to be re-rated starting from a corrected game(s).)
can be edited, inserted, or deleted with games (If game data is
edited.) automatically be re-rated.  5) Et cetera ...

My current project structure is:

/Projects
    /rating_calculator
        /rating_calculator
            __init__.py
            main.py
        /tests
            __init__.py
            test_main.py

I have started my coding with a RatingCalculator class.  The intent of
this class is to gather all methods together needed to validate and
calculate chess ratings.  My intent is to only ever have a single
instance of this class existing during a given running of the program.
(BTW, is there a technique to _guarantee_ that this is always true?)
I am only at the very beginning of coding this class.  I have not
added any methods yet.  Currently I am adding class constants that
will be used in this class' methods.  These constants are for internal
class use only and should not be altered from outside the class.  Here
is the current state of the main.py program (Which will probably be
broken into multiple modules as the project develops.):

=================================================================================
#!/usr/bin/env python3

"""Module to process chess ratings."""

class RatingCalculator:
    """This class contains methods to validate and calculate chess ratings."""

    # Overestimated extremes for possible chess rating values.  Values outside
    # this range should not be achievable.

    _LOWEST_POSSIBLE_RATING = 0
    _HIGHEST_POSSIBLE_RATING = 3000

    # Fundamental constants for use in the chess rating formula.  The keys to
    # these values are tuples giving the rating ranges for which these
    # K-factors are valid.

    _K_MULTIPLIERS = {
            (_LOWEST_POSSIBLE_RATING, 2099): 0.04,
            (2100, 2399): 0.03,
            (2400, _HIGHEST_POSSIBLE_RATING): 0.02}

    _K_ADDERS = {
            (_LOWEST_POSSIBLE_RATING, 2099): 16,
            (2100, 2399): 12,
            (2400, _HIGHEST_POSSIBLE_RATING): 8}
=================================================================================

The test code in test_main.py is:

=================================================================================
#!/usr/bin/env python3

"""Module to test all functions and methods of main.py."""

import unittest
import rating_calculator.main as main

class TestRatingCalculatorConstants(unittest.TestCase):
    # Check that the constants in RatingCalculator have the proper values.

    def setUp(self):
        # Create instance of RatingCalculator for use in the following tests.
        # Create tuple of test-value pairs to interate over in subtests.

        self.rating_calculator = main.RatingCalculator()
        self.test_value_pairs = (
                (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0),
                (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000),
                (self.rating_calculator._K_MULTIPLIERS[(
                    self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)],
                    0.04),
                (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)], 0.03),
                (self.rating_calculator._K_MULTIPLIERS[(2400,
                    self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 0.02),
                (self.rating_calculator._K_ADDERS[(
                    self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)],
                    16),
                (self.rating_calculator._K_ADDERS[(2100, 2399)], 12),
                (self.rating_calculator._K_ADDERS[(2400,
                    self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8))


    def test_class_constants(self):
        # Check that all class constants have the correct values.

        for tested_item, expected_value in self.test_value_pairs:
            with self.subTest():
                self.assertEqual(tested_item, expected_value)


if __name__ == '__main__':
    unittest.main()
=================================================================================

Instead of doc strings in the test code, I have used comments based on
something I read online.  The point of doing this was so the doc
strings would _not_ show up in the test run output.  Is this
worthwhile advice to follow?

I'm looking forwards to everyone's thoughts.

TIA!


-- 
boB

From steve at pearwood.info  Sun Aug 13 02:42:04 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 13 Aug 2017 16:42:04 +1000
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
Message-ID: <20170813064204.GP7395@ando.pearwood.info>

I haven't had a chance to read the entire post in detail, but one thing 
which stands out:

On Sun, Aug 13, 2017 at 12:22:52AM -0500, boB Stepp wrote:

> I have started my coding with a RatingCalculator class.  The intent of
> this class is to gather all methods together needed to validate and
> calculate chess ratings.  My intent is to only ever have a single
> instance of this class existing during a given running of the program.
> (BTW, is there a technique to _guarantee_ that this is always true?)

Yes, this is called the "Singleton" design pattern, which is very 
possibly the most popular and common design pattern in OOP.

It is also very possibly the *least appropriate* use of OOP techniques 
imaginable, so much so that many people consider it to be an 
anti-pattern to be avoided:

https://www.michaelsafyan.com/tech/design/patterns/singleton

(follow the links at the bottom of the page for more information about 
why singletons are considered harmful).

It is popular because:

- it is easy to understand;

- it is easy to program, at least in languages like Java and C++ 
  (less so in Python);

- consequently it is often the first OOP design patterns taught;

- and it makes up for a deficiency in Java, or at least the Java
  philosophy, namely the lack or avoidance of top-level functions.

http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html

In Python, the equivalent to the singleton is the module. If you have a 
class full of methods which is only ever going to be instantiated once, 
*almost always* the solution in Python is to use a module full of 
functions.

There are few exceptions, but they're generally identity-objects only, 
with little or no state and few if any methods:

- None
- NotImplemented
- Ellipsis
- True and False (okay, duotons not singletons)

I can't think of any other obvious examples.

By "identity-object", I mean an object whose value is synonymous with 
its identity, rather than two separate aspects of the object.

With regular objects, their value is independent of their identity. 
Their identity is "which particular object is this?" while their value 
is separate: you can easily have you have two floats with same value 
(say, both 1.25) without them necessarily being the same object. 
Likewise we can have two distinct lists which happen to have the same 
value: they both have the value [1, 2, 3], but they're different lists 
with the same value rather than the same list.

With regular objects, just because they have the same value doesn't 
necessarily mean they must be the same object, they may be distinct 
objects with the same value.

But the value of None is not separate from its identity. None has no 
value *except the fact that it is the None object*. Its value is not 
separate from its identity, its value is its identity.

So, coming back to your RatingCalculator class:

(1) Can you think of any possible circumstances where you might want two 
distinct RatingCalculators at the same time? Could you not have two 
different calculation methods? If so, then use a class, but allow it to 
be instantiated as often as you need.

(2) If there is absolutely no possible reason to want two such 
calculators, then there is little reason to use a class at all. 
Singletons are just global-level state disguised as an object.


A third option:

Look at the source code for the random module. It has a Random class, so 
that you can have as many different, *independent* random number 
generators as you need. They can be subclassed to use different 
mechanisms for generating pseudo-random numbers, or they can use the 
same algorithm but be in different internal states.

But since *most* people don't need more than one RNG at a time, there's 
also a hidden instance, pre-instantiated when the module is imported for 
the first time, which is used to provide module-level RNG functions. The 
caller doesn't need to know that under the hood there's a private 
instance. Advanced users can create their own instances, while simple 
cases just call the module-level functions.



-- 
Steve

From robertvstepp at gmail.com  Sun Aug 13 03:09:59 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 13 Aug 2017 02:09:59 -0500
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <20170813064204.GP7395@ando.pearwood.info>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <20170813064204.GP7395@ando.pearwood.info>
Message-ID: <CANDiX9JR5+3YcWDAfjBkUpUJ2fR3CLxTwKt5Yj9LdrFNNnxmaQ@mail.gmail.com>

It is rather late here, so I won't get to the links until much later
today, but ...

On Sun, Aug 13, 2017 at 1:42 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> I haven't had a chance to read the entire post in detail, but one thing
> which stands out:
>
> On Sun, Aug 13, 2017 at 12:22:52AM -0500, boB Stepp wrote:
>
>> I have started my coding with a RatingCalculator class.  The intent of
>> this class is to gather all methods together needed to validate and
>> calculate chess ratings.  My intent is to only ever have a single
>> instance of this class existing during a given running of the program.
>> (BTW, is there a technique to _guarantee_ that this is always true?)
>
> Yes, this is called the "Singleton" design pattern, which is very
> possibly the most popular and common design pattern in OOP.
>
> It is also very possibly the *least appropriate* use of OOP techniques
> imaginable, so much so that many people consider it to be an
> anti-pattern to be avoided:

[...]

> In Python, the equivalent to the singleton is the module. If you have a
> class full of methods which is only ever going to be instantiated once,
> *almost always* the solution in Python is to use a module full of
> functions.

Hmm.  I should have gone with my gut instinct.  I did not see any
value in a one-object class, and felt I should just have a module with
these functions.  But the goal of this project is to use OOP, so my
intended design was to *force* these methods into a class and use the
class as a convenient container.  OTOH, my other classes I plan to
code -- Player, Game and possibly Database -- make more sense as
classes as the first two will have multiple instances with different
states per object.  And eventually there will be a GUI in tkinter
which is naturally organized by classes.

Thanks, Steve.  This is especially useful feedback as it enhances my
understanding of when and how to implement classes vs. collections of
functions.

boB

From alan.gauld at yahoo.co.uk  Sun Aug 13 04:20:30 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 13 Aug 2017 09:20:30 +0100
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
Message-ID: <omp247$sgs$1@blaine.gmane.org>

On 13/08/17 06:22, boB Stepp wrote:

> The intent of this project is more than just calculate chess ratings.
> I also envision being able to store a record of all game results and
> player information for my school chess players that I give lessons to.

That's fair enough but OOP or no OOP the basic advice is the same:
divide and conquer. Make the admin and logic parts of the application
separate and work on the core of each. Bring them together via the
UI (which initially may be a set of CLI tools...).

> I have started my coding with a RatingCalculator class.  The intent of
> this class is to gather all methods together needed to validate and
> calculate chess ratings.  

That may be appropriate in that it is often the case that you have a
single class representing the applications a whole. But a calculator
sounds like a low level helper class to me, possibly encapsulating the
detailed algorithms used top create the ratings. I'd expect there to be
potentially several subclasses representing different algorithms. I'd
expect the calculator instances to be passed as an object into the
rate() method of a game object...

> My intent is to only ever have a single
> instance of this class existing during a given running of the program.

I notice Steven's post, to which I'll add amen.
Singletons in Python are rarely needed, just make your game
a module. Maybe rethink the role of the calculator class.

> added any methods yet.  Currently I am adding class constants that
> will be used in this class' methods. 

Since internal data/attributes should support the operations
its usual to start with the operations before defining
the supporting data. Seriously consider using the CRC
methodology to identify and describe your projects classes.
It can be in a single document rather than physical cards,
the important thing is to briefly describe what each class
is called, its responsibilities(often becoming methods)
and collaborators (other classes which become attributes
or method parameters).

>  These constants are for internal
> class use only and should not be altered from outside the class.  

It sounds like they are to be shared values across
methods of various objects/methods, that suggests
putting them in a shared class or module.

> is the current state of the main.py program (Which will probably be
> broken into multiple modules as the project develops.):

While Python doesn't require using a module per class, it is better to
keep related classes in a single module so I strongly suggest breaking
it into multiple modules. At the least 3: rating engine, admin and UI.

> """Module to process chess ratings."""
> 
> class RatingCalculator:
>     """This class contains methods to validate and calculate chess ratings."""

I'd suggest that validation and calculation are two very different
things. Probably requiring separate classes. But we need more detail
on the objects involved. What does a rating rate - a Game? a Move? a
strategy? And what does validation validate? A rating perhaps?
You are in danger of focusing on the verbs (rating calculate,
create, edit, etc rather than the objects that do these things.
You need to turn your initial thoughts away from what the application
does (traditional procedural coding style) and onto thinking
about what kind of objects make up the application. It's common
to start with a fairly long list then, as you apply CRC analysis(*),
realize that many of the objects are only attributes. But it's better
to start with too many objects than to try to squeeze functionality
into just a few uber-objects.


(*)If you discover that a candidate class has no responsibility
except holding one or maybe two pieces of information, or that
it only collaborates with one other object you may decide it
only needs be an attribute not a full class. Also, especially
in Python, many collections of classes will turn out to be
standard container types such as lists, dicts, tuples etc.
Or standard classes such as dates/times. Making these early
win decisions is one of the biggest reasons for doing CRC
analysis IMHO.

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



From __peter__ at web.de  Sun Aug 13 04:52:19 2017
From: __peter__ at web.de (Peter Otten)
Date: Sun, 13 Aug 2017 10:52:19 +0200
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
Message-ID: <omp3vt$m9s$1@blaine.gmane.org>

boB Stepp wrote:

> I mentioned in one of the recent threads that I started that it is
> probably time for me to attempt a substantial project using the OO
> paradigm.  I have had no coursework or training in OOP other than my
> recent self-studies.  Everything (Other than toy practice examples.) I
> have coded to date has been strictly procedural, similar to what I
> learned in FORTRAN ages ago.  Also, I am continuing to try to do TDD
> and keep things DRY.  So I am hoping for a thorough critique of what I
> will shortly present.  Everything is fair game!  Hopefully my
> self-esteem is up to this critique!
> 
> The intent of this project is more than just calculate chess ratings.
> I also envision being able to store a record of all game results and
> player information for my school chess players that I give lessons to.
> Some functionality I will strive to include:  1) Be able to re-rate
> all games from a given date to the present.  2) Record demographic
> information about my players, such as names, current school year,
> current grade, etc.  3) Have a very friendly GUI so that when I have a
> finished project, a student could easily take over responsibility of
> maintaining the school's player ratings, if I so choose to allow this.
> 4) Having an editor where games and player data (But NOT ratings;
> these would have to be re-rated starting from a corrected game(s).)
> can be edited, inserted, or deleted with games (If game data is
> edited.) automatically be re-rated.  5) Et cetera ...
> 
> My current project structure is:
> 
> /Projects
>     /rating_calculator
>         /rating_calculator
>             __init__.py
>             main.py
>         /tests
>             __init__.py
>             test_main.py
> 
> I have started my coding with a RatingCalculator class.  The intent of
> this class is to gather all methods together needed to validate and
> calculate chess ratings.  My intent is to only ever have a single
> instance of this class existing during a given running of the program.

Why?

> (BTW, is there a technique to _guarantee_ that this is always true?)

Why? Would it harm one instance if there were another one? If so you have 
global state which usually runs counter to the idea of a class.

> I am only at the very beginning of coding this class.  I have not
> added any methods yet.  Currently I am adding class constants that
> will be used in this class' methods.  These constants are for internal
> class use only and should not be altered from outside the class.  

Still, a good unit test might be to initialise a RatingCalcultator with 
different "highest possible ratings" and then verify for each instance that 
actual ratings never exceed the specified value.

> Here
> is the current state of the main.py program (Which will probably be
> broken into multiple modules as the project develops.):
> 
> 
=================================================================================
> #!/usr/bin/env python3
> 
> """Module to process chess ratings."""
> 
> class RatingCalculator:
>     """This class contains methods to validate and calculate chess
>     ratings."""
> 
>     # Overestimated extremes for possible chess rating values.  Values
>     # outside this range should not be achievable.

If there are no hard limits, why give a limit at all?

> 
>     _LOWEST_POSSIBLE_RATING = 0

Again, this is just a number. Is it really worthwile explicit checking in a 
unit test? The most relevant tests address behaviour.

>     _HIGHEST_POSSIBLE_RATING = 3000
> 
>     # Fundamental constants for use in the chess rating formula.  The keys
>     # to these values are tuples giving the rating ranges for which these
>     # K-factors are valid.
> 
>     _K_MULTIPLIERS = {
>             (_LOWEST_POSSIBLE_RATING, 2099): 0.04,

The Python way uses half-open intervals. This has the advantage that there 
is a well-defined k-multiplier for a rating of 2099.5. Note that if you 
apply that modification you no longer need any upper limits. Use bisect (for 
only threee values linear search is OK, too) to find the interval from a 
list like [0, 2100, 2400], then look up the multiplier in a second list 
[0.04, 0.03, 0.02])

>             (2100, 2399): 0.03,
>             (2400, _HIGHEST_POSSIBLE_RATING): 0.02}
> 
>     _K_ADDERS = {
>             (_LOWEST_POSSIBLE_RATING, 2099): 16,
>             (2100, 2399): 12,
>             (2400, _HIGHEST_POSSIBLE_RATING): 8}
> 
=================================================================================
> 
> The test code in test_main.py is:
> 
> 
=================================================================================
> #!/usr/bin/env python3
> 
> """Module to test all functions and methods of main.py."""
> 
> import unittest
> import rating_calculator.main as main
> 
> class TestRatingCalculatorConstants(unittest.TestCase):
>     # Check that the constants in RatingCalculator have the proper values.
> 
>     def setUp(self):
>         # Create instance of RatingCalculator for use in the following
>         # tests. Create tuple of test-value pairs to interate over in
>         # subtests.
> 
>         self.rating_calculator = main.RatingCalculator()
>         self.test_value_pairs = (
>                 (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0),

With the _ you are making these constants implementation details. Isn't one 
goal of unit tests to *allow* for changes in the implementation while 
keeping the public interface?

>                 (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000),
>                 (self.rating_calculator._K_MULTIPLIERS[(
>                     self.rating_calculator._LOWEST_POSSIBLE_RATING,
>                     2099)], 0.04),
>                 (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)],
>                 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400,
>                     self.rating_calculator._HIGHEST_POSSIBLE_RATING)],
>                     0.02),
>                 (self.rating_calculator._K_ADDERS[(
>                     self.rating_calculator._LOWEST_POSSIBLE_RATING,
>                     2099)], 16),
>                 (self.rating_calculator._K_ADDERS[(2100, 2399)], 12),
>                 (self.rating_calculator._K_ADDERS[(2400,
>                     self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8))
> 
> 
>     def test_class_constants(self):
>         # Check that all class constants have the correct values.
> 
>         for tested_item, expected_value in self.test_value_pairs:
>             with self.subTest():
>                 self.assertEqual(tested_item, expected_value)
> 
> 
> if __name__ == '__main__':
>     unittest.main()
> 
=================================================================================
> 
> Instead of doc strings in the test code, I have used comments based on
> something I read online.  The point of doing this was so the doc
> strings would _not_ show up in the test run output.  Is this
> worthwhile advice to follow?

No. Why would you think it is? 

Also, it looks like only the first line of the test_xxx() methods' docstring 
is shown by default:

$ cat tmp.py
import unittest
import os

ok = bool(os.environ.get("OK"))

class A(unittest.TestCase):
    """NOT EVER SHOWN"""
    def test_foo(self):
        """
        HIDDEN.
        """
        self.assertTrue(ok)

    def test_bar(self):
        """SEEN.
        hidden
        hidden
        """
        self.assertTrue(ok)

if __name__ == "__main__":
    unittest.main()
$ python3 tmp.py 
FF
======================================================================
FAIL: test_bar (__main__.A)
SEEN.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tmp.py", line 19, in test_bar
    self.assertTrue(ok)
AssertionError: False is not true

======================================================================
FAIL: test_foo (__main__.A)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tmp.py", line 12, in test_foo
    self.assertTrue(ok)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=2)
$ 

> I'm looking forwards to everyone's thoughts.

Values are the most volatile and least important part of a program.
Start coding with the algorithms and tests covering those.


From robertvstepp at gmail.com  Sun Aug 13 16:15:10 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 13 Aug 2017 15:15:10 -0500
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
Message-ID: <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>

Based upon the feedback thus far (Many thanks!) I think that perhaps I
should expand on my design thoughts as I have already stubbed my big
toe at the very start!

On Sun, Aug 13, 2017 at 12:22 AM, boB Stepp <robertvstepp at gmail.com> wrote:

> The intent of this project is more than just calculate chess ratings.

CALCULATION OF RATINGS

My calculation of a new chess rating is a simpler process than what is
used for FIDE Elo ratings or USCF Elo ratings for over-the-board play.
Instead, I am adapting the USCF (United States Chess Federation)
correspondence chess rating formula for use with my students.  These
students usually come to me often not even knowing the moves and rules
of the game.  They have no previous tournament chess experience and in
general are quite weak players even if they sometimes believe
otherwise. ~(:>))  A link to the USCF's explanation of this rating
system is:  http://www.uschess.org/content/view/7520/393/

It is not very well-written in my opinion.  But anyway ... The basic formula is:

new_rating = old_rating + K_MULTIPLIER * (opponent_rating -
old_rating) + K_ADDER * (your_result - opponent_result)

If you win your_result = 1; lose = 0; draw = 0.5.  Note that the
opponent's result would be, respectively, 0, 1 and 0.5, corresponding
to these values of your_result.

I am not using the article's section on unrated players.  This is of
little use to me as I usually start off without anyone who has ever
had a chess rating.  So there is no existing rating pool to
meaningfully compare my unrated players against.  So I start out each
unrated player with a rating of 1000.  For most of my students who
already know and play chess, this turns out to be a slightly generous
estimate of their rating if I were to compare them to the USCF
over-the-board rating population.

Another change from the article I am making is that if there is more
than a 350 rating point difference between players, then the game is
rated as if it is a 350 point difference.  I have changed this to 400
points as I feel that the higher rated player should _not_ gain any
rating points for beating the lower rated player.  In practice I am
the only person 400+ points greater than anyone.  To date I have a
100% win rate against my students, so I would rather they not obsess
about losing rating points against their peers if I have to fill in
for a game due to an odd number of players showing up.

There are several conditionals that have to be applied to calculate
the rating even in this simplified system.  K_MULTIPLIER and K_ADDER
are dependent on whether the player's old_rating falls into one of
these rating ranges:  1)  0 - 2099; 2) 2100 - 2399; 3) >= 2400.
Additionally, if the initial new_rating calculation causes new_rating
to fall into a different K-factor rating range, then the new rating
must be proportionately adjusted for the number of points that fall
into the new K-factor rating range, using a ratio of the new and old
K-factors.

So based on what Steve said, the rating calculation makes more sense
to be done with functions.  One of the things I wish to do with the
completed program, is to enter all of my old game data spanning ~ 5
years, and have the program re-rate everything from scratch.  So I do
not see how it would be helpful to create a new RatingCalculator
instance for each game.

PERSISTENT STORAGE OF GAME DATA AND PLAYER DATA

I've decided not to use an actual database as I will never have so
much data that it cannot be fully loaded into RAM for even quite
modest PCs.  The approach I am thinking of taking is using a
dictionary of dictionaries to store the game data and player data.
Something like:

players = {0: {'last name': 'Smith', 'first name': 'John', ... },
           1: {'last name': 'Doe', 'first name': 'Doe', ... },
           ... ,
           n: {...}}

and similarly for games.  I would use the csv library's dictread and
dictwrite methods to load into memory and on program exit write back
to disk these two dictionaries, which are meant to mimic two database
tables.

REPORT GENERATION

There are a variety of reports that I would like to be able to print
to screen or paper.  Things such as a "Top x List" of rated players,
full rating list sorted from highest rating to lowest, rating lists
for the current school year only or a particular past school year, and
so.  I could see wanting to sort such lists by various criteria
depending on the type of report I would like to generate.  Currently
this section of the program is a big gray area for me, but I see no
reason why my two dictionaries cannot be manipulated to pull the
desired results for each imagined type of report.

USER INTERFACE

Until all of the above is worked out, I will use a CLI, perhaps even
play around with the curses library, which I have been meaning to do.
Once I get an overall result that I am happy with, I will develop a
GUI in tkinter.  My intent is to go as Alan suggests and keep the UI
well-decoupled from the rest of the program, no matter if it is CLI or
GUI.

PLANNING ALL OF THIS OUT -- HOW MUCH DETAIL?

I generally start as above by dividing things up into broad areas of
functionality and then picking the seeming easiest to start work on,
which is why I began with the RatingCalculator (Which will shortly
become the calculate_ratings module instead of a class.).  It seemed
to be a rather straightforward translation of a formula with various
conditions into code, returning the newly calculated ratings (One per
player in a game.).  All ratings must be positive integers; floats
must be rounded to nearest positive integer. It is theoretically
conceivable that someone could eventulally acquire a rating of zero,
but in practice that should be impossible and if that result turns up
I would be suspicious of bugs in the program.  Likewise I am planning
to use 3000 as an upper limit.  Current super-strong chess programs
can exceed this lofty height, and the very best humans in the world
might get in spitting distance of this limit, but grade school
students that have minimal experience with chess?  I am using these
bounds as sanity checks for the program for unforeseen issues.  Note
that in the starting code I posted, I had yet to reach the steps where
I would make use of these two bounds.

So how detailed should I plan out each broad section of the program
before writing any code?  Alan seems to be suggesting getting a firm
handle on initially imagined objects and their methods before any code
writing.

I hope this describes better what I am striving to accomplish.

Thanks!

boB

From mysecretrobotfactory at gmail.com  Sun Aug 13 16:07:53 2017
From: mysecretrobotfactory at gmail.com (Michael C)
Date: Sun, 13 Aug 2017 13:07:53 -0700
Subject: [Tutor] "Path tree"
Message-ID: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>

Hi all:

I am trying to formulate a "path-finding" function, and I am stuck on this
problem:

Please look at the picture attached: Those dots are coordinates of (x,y),
and this tree can be thought of as a list of tuples, with each tuple
consisting of (x,y).  Now I am trying to make a function go through this
list of tuples and then return the "path." to go from, say, 4 to 8. If I
simply compute for the dot for shortest distance, then the solution would
be to go from 4 to 8 direct, but that doesn't work, because the correct
solution should have been 4,3,2,5,6,8.


How do I do this?

Thanks!

From alan.gauld at yahoo.co.uk  Sun Aug 13 18:49:20 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 13 Aug 2017 23:49:20 +0100
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
Message-ID: <omql19$7qj$1@blaine.gmane.org>

On 13/08/17 21:15, boB Stepp wrote:

I return to the point I made about focusing on the
objects not the functionality.

> It is not very well-written in my opinion.  But anyway ... The basic formula is:
> 
> new_rating = old_rating + K_MULTIPLIER * (opponent_rating -
> old_rating) + K_ADDER * (your_result - opponent_result)

What is being rated? A player? A game? a set of games?
The rating calculation should probably be a method of
the object being rated rather than a standalone function.

If you make it a function you will probably have to pass
in lots of data objects (or worse use a lot of globals).
In OOP you want the data to be in the object and the
method to use that data to achieve its aim.

> I generally start as above by dividing things up into broad areas of
> functionality 

Which is exactly how you write procedural code - the technique
is called functional decomposition.

But if your objective is to use OOP you should start by identifying
the objects. Then you can assign the functionality(responsibilities)
to which ever object (or set of objects) is appropriate.


> to be a rather straightforward translation of a formula with various
> conditions into code, returning the newly calculated ratings 

Note that I'm not saying your approach is wrong in a general case,
it may well be the most appropriate approach for this application.
But it will not easily lead to an OOP style solution, and that I
thought was the secondary(or even primary?) objective of this
exercise?

> So how detailed should I plan out each broad section of the program
> before writing any code?  Alan seems to be suggesting getting a firm
> handle on initially imagined objects and their methods before any code
> writing.

You need some kind of idea of the classes you are going to write.
The CRC description only needs to be a few lines scribbled on a
sheet of paper or in a text editor. In OOP you are building classes that
represent instances. Your solution is an interaction between the
instances (objects). Without a fairly clear idea of how the objects
interact you can't make a sensible start. You don't need to analyse
the whole system (and indeed should not do so) but start with a
couple of basic use cases - what initiates the action? What are
the  preconditions(eg. data etc), the outcomes, the possible error
conditions. When you understand a use case enough to code it, do so.
Or even just the initial class/object.

It's a good idea to get an early code structure in place, maybe
a Player class? It seems that this is the thing being rated.
Maybe a game class since it seems that game (results and players)
are used in the rating algorithm. So your Player probably needs
a list of past games?

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



From robertvstepp at gmail.com  Sun Aug 13 19:04:50 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 13 Aug 2017 18:04:50 -0500
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <omp3vt$m9s$1@blaine.gmane.org>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <omp3vt$m9s$1@blaine.gmane.org>
Message-ID: <CANDiX9KxMfyHAAVOqpuq5kUFBRYPk_HMxF3WnyEF=dRBT_4p8w@mail.gmail.com>

On Sun, Aug 13, 2017 at 3:52 AM, Peter Otten <__peter__ at web.de> wrote:
> boB Stepp wrote:

>> I am only at the very beginning of coding this class.  I have not
>> added any methods yet.  Currently I am adding class constants that
>> will be used in this class' methods.  These constants are for internal
>> class use only and should not be altered from outside the class.
>
> Still, a good unit test might be to initialise a RatingCalcultator with
> different "highest possible ratings" and then verify for each instance that
> actual ratings never exceed the specified value.

I just had not gotten around to doing this yet.

> =================================================================================
>> #!/usr/bin/env python3
>>
>> """Module to process chess ratings."""
>>
>> class RatingCalculator:
>>     """This class contains methods to validate and calculate chess
>>     ratings."""
>>
>>     # Overestimated extremes for possible chess rating values.  Values
>>     # outside this range should not be achievable.
>
> If there are no hard limits, why give a limit at all?

My thinking was to put in a sanity check.  The ratings should fall
into sensible limits.

>>
>>     _LOWEST_POSSIBLE_RATING = 0
>
> Again, this is just a number. Is it really worthwile explicit checking in a
> unit test? The most relevant tests address behaviour.

Shouldn't I check for inadvertent changing of what are constants by
later modifications of the code?

>>     _HIGHEST_POSSIBLE_RATING = 3000
>>
>>     # Fundamental constants for use in the chess rating formula.  The keys
>>     # to these values are tuples giving the rating ranges for which these
>>     # K-factors are valid.
>>
>>     _K_MULTIPLIERS = {
>>             (_LOWEST_POSSIBLE_RATING, 2099): 0.04,
>
> The Python way uses half-open intervals. This has the advantage that there
> is a well-defined k-multiplier for a rating of 2099.5. Note that if you
> apply that modification you no longer need any upper limits. Use bisect (for
> only threee values linear search is OK, too) to find the interval from a
> list like [0, 2100, 2400], then look up the multiplier in a second list
> [0.04, 0.03, 0.02])

Note:  Valid ratings can only be positive integers.  No floats allowed
in the final rating result or in the initial input of an established
rating that is to be changed.

So you are suggesting doing something like:

-----------------------------------------------------------------------------------
py3: from bisect import bisect
py3: def get_k_factors(rating):
...     RATING_BREAKPOINTS = [0, 2100, 2400]
...     K_ADDERS = [16, 12, 8]
...     K_MULTIPLIERS = [0.04, 0.03, 0.02]
...     index = bisect(RATING_BREAKPOINTS, rating) - 1
...     k_adder = K_ADDERS[index]
...     k_multiplier = K_MULTIPLIERS[index]
...     return k_adder, k_multiplier
...
py3: get_k_factors(1900)
(16, 0.04)
py3: get_k_factors(2100)
(12, 0.03)
py3: get_k_factors(2399)
(12, 0.03)
py3: get_k_factors(2400)
(8, 0.02)
-----------------------------------------------------------------------------------

I like it!  It will save me from having to use a bunch of conditionals.


>>             (2100, 2399): 0.03,
>>             (2400, _HIGHEST_POSSIBLE_RATING): 0.02}
>>
>>     _K_ADDERS = {
>>             (_LOWEST_POSSIBLE_RATING, 2099): 16,
>>             (2100, 2399): 12,
>>             (2400, _HIGHEST_POSSIBLE_RATING): 8}
>>
> =================================================================================
>>
>> The test code in test_main.py is:
>>
>>
> =================================================================================
>> #!/usr/bin/env python3
>>
>> """Module to test all functions and methods of main.py."""
>>
>> import unittest
>> import rating_calculator.main as main
>>
>> class TestRatingCalculatorConstants(unittest.TestCase):
>>     # Check that the constants in RatingCalculator have the proper values.
>>
>>     def setUp(self):
>>         # Create instance of RatingCalculator for use in the following
>>         # tests. Create tuple of test-value pairs to interate over in
>>         # subtests.
>>
>>         self.rating_calculator = main.RatingCalculator()
>>         self.test_value_pairs = (
>>                 (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0),
>
> With the _ you are making these constants implementation details. Isn't one
> goal of unit tests to *allow* for changes in the implementation while
> keeping the public interface?

I don't think I am understanding your thoughts.  Would you please
provide an illustrative example?  I am concerned that later program
development or maintenance might inadvertently alter values that are
expected to be constants.

>>                 (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000),
>>                 (self.rating_calculator._K_MULTIPLIERS[(
>>                     self.rating_calculator._LOWEST_POSSIBLE_RATING,
>>                     2099)], 0.04),
>>                 (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)],
>>                 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400,
>>                     self.rating_calculator._HIGHEST_POSSIBLE_RATING)],
>>                     0.02),
>>                 (self.rating_calculator._K_ADDERS[(
>>                     self.rating_calculator._LOWEST_POSSIBLE_RATING,
>>                     2099)], 16),
>>                 (self.rating_calculator._K_ADDERS[(2100, 2399)], 12),
>>                 (self.rating_calculator._K_ADDERS[(2400,
>>                     self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8))
>>
>>
>>     def test_class_constants(self):
>>         # Check that all class constants have the correct values.
>>
>>         for tested_item, expected_value in self.test_value_pairs:
>>             with self.subTest():
>>                 self.assertEqual(tested_item, expected_value)
>>
>>
>> if __name__ == '__main__':
>>     unittest.main()
>>
> =================================================================================
>>
>> Instead of doc strings in the test code, I have used comments based on
>> something I read online.  The point of doing this was so the doc
>> strings would _not_ show up in the test run output.  Is this
>> worthwhile advice to follow?
>
> No. Why would you think it is?

Because some article online (I don't recall the source now.) convinced
me that having doc strings showing up in unittest output contributed
unnecessary clutter for no benefit.

>> I'm looking forwards to everyone's thoughts.
>
> Values are the most volatile and least important part of a program.
> Start coding with the algorithms and tests covering those.

I was just looking for the lowest hanging fruit to get an easy start
on this project, and use it as a check to see if I was going off in
inadvisable directions.


-- 
boB

From robertvstepp at gmail.com  Sun Aug 13 19:17:31 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 13 Aug 2017 18:17:31 -0500
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <omql19$7qj$1@blaine.gmane.org>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
 <omql19$7qj$1@blaine.gmane.org>
Message-ID: <CANDiX9L4=qe-pJF-_fpOvA-Gdq-YUbq1=rO8GFSrpi9y6Z1mAg@mail.gmail.com>

On Sun, Aug 13, 2017 at 5:49 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 13/08/17 21:15, boB Stepp wrote:
>
> I return to the point I made about focusing on the
> objects not the functionality.
>
>> It is not very well-written in my opinion.  But anyway ... The basic formula is:
>>
>> new_rating = old_rating + K_MULTIPLIER * (opponent_rating -
>> old_rating) + K_ADDER * (your_result - opponent_result)
>
> What is being rated? A player? A game? a set of games?
> The rating calculation should probably be a method of
> the object being rated rather than a standalone function.

The result of a game between two players results in the need to
calculate new ratings for both players.  Ratings are attributes of
players.

>> I generally start as above by dividing things up into broad areas of
>> functionality
>
> Which is exactly how you write procedural code - the technique
> is called functional decomposition.

Got me there!  Still stuck in the old procedural paradigm.

> But if your objective is to use OOP you should start by identifying
> the objects. Then you can assign the functionality(responsibilities)
> to which ever object (or set of objects) is appropriate.
>
>
>> to be a rather straightforward translation of a formula with various
>> conditions into code, returning the newly calculated ratings
>
> Note that I'm not saying your approach is wrong in a general case,
> it may well be the most appropriate approach for this application.
> But it will not easily lead to an OOP style solution, and that I
> thought was the secondary(or even primary?) objective of this
> exercise?

You understand correctly!  The primary purpose of this project is
breakout of procedural programming and break into OOP.

>> So how detailed should I plan out each broad section of the program
>> before writing any code?  Alan seems to be suggesting getting a firm
>> handle on initially imagined objects and their methods before any code
>> writing.
>
> You need some kind of idea of the classes you are going to write.
> The CRC description only needs to be a few lines scribbled on a
> sheet of paper or in a text editor. In OOP you are building classes that
> represent instances. Your solution is an interaction between the
> instances (objects). Without a fairly clear idea of how the objects
> interact you can't make a sensible start. You don't need to analyse
> the whole system (and indeed should not do so) but start with a
> couple of basic use cases - what initiates the action? What are
> the  preconditions(eg. data etc), the outcomes, the possible error
> conditions. When you understand a use case enough to code it, do so.
> Or even just the initial class/object.

I just finished reading a couple of online articles about CRC cards.
I have some old index cards lying around.  I will have at it.

> It's a good idea to get an early code structure in place, maybe
> a Player class? It seems that this is the thing being rated.
> Maybe a game class since it seems that game (results and players)
> are used in the rating algorithm. So your Player probably needs
> a list of past games?

The two most obvious classes that jumped to my mind from the get-go
are Player and Game.

Thanks, Alan!

-- 
boB

From guettliml at thomas-guettler.de  Mon Aug 14 09:20:51 2017
From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=)
Date: Mon, 14 Aug 2017 15:20:51 +0200
Subject: [Tutor] Percentage of installations without setuptools (Was if
 __name__=='__main__' ...)
In-Reply-To: <20170813001245.GN7395@ando.pearwood.info>
References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de>
 <20170813001245.GN7395@ando.pearwood.info>
Message-ID: <a9303ab8-72ec-ea80-2d50-5df71a85c78d@thomas-guettler.de>



Am 13.08.2017 um 02:12 schrieb Steven D'Aprano:
> On Fri, Aug 11, 2017 at 02:35:00PM +0200, Thomas G?ttler wrote:
> 
>> How high is the percentage of python installation which don't have
>> setuptools?
>>
>> I have no clue. Is it 5%, 10%, 15% ...?
>>
>> I know there is no definite answer to this question. But you can guess this
>> better than me.
> 
> Somewhere between 0.1% and 99.9%.
> 
> For what little it is worth, out of the 9 versions of Python I have
> installed on my personal machines, setuptools is installed for 4 of
> them. On work machines, 2 out of 5 have setuptools installed. So in
> total, 6 out of 14 Python installations I have access to include
> setuptools. So 57% *don't* have setup tools.
> 
> Really Thomas, why do you care?

Good question. Why do I care ...

If there is no solid ground, no sane defaults, then young and talented programmers
waste time. I just don't know why, but this makes me feel pain.

> If you want to require setuptools for
> your packages, go right ahead. If you want to tell people that using
> setuptools is the best choice, or the most popular choice, or the
> smartest choice, do so.
> 
> Just don't say it is the "default choice" because that is silly. The
> whole purpose of something being *default* is so that you DON'T have to
> make a choice. Obviously that doesn't apply to choosing a packaging
> library, and especially not to choosing a packaging language which may
> not even be present. Even if its only missing 1% of the time.

> As a third-party author, the sorts of people who don't have setuptools
> installed either won't be installing your software at all, or will be
> installing it from source.
> 
> 

-- 
Thomas Guettler http://www.thomas-guettler.de/

From mats at wichmann.us  Mon Aug 14 11:19:42 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 14 Aug 2017 09:19:42 -0600
Subject: [Tutor] "Path tree"
In-Reply-To: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
References: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
Message-ID: <8754dee0-d575-aa9a-03a8-de65b9aff44f@wichmann.us>

On 08/13/2017 02:07 PM, Michael C wrote:
> Hi all:
> 
> I am trying to formulate a "path-finding" function, and I am stuck on this
> problem:
> 
> Please look at the picture attached: Those dots are coordinates of (x,y),
> and this tree can be thought of as a list of tuples, with each tuple
> consisting of (x,y).  Now I am trying to make a function go through this
> list of tuples and then return the "path." to go from, say, 4 to 8. If I
> simply compute for the dot for shortest distance, then the solution would
> be to go from 4 to 8 direct, but that doesn't work, because the correct
> solution should have been 4,3,2,5,6,8.
>
> How do I do this?

There is no picture, don't know if you forgot to attach, or if it got
stripped by the mailing list software (the latter does happen, although
some seem to get through).

There is quite some on path-walking solvers in Python if you search a
bit, although when I looked just now it was not as easy to find useful
stuff as I remembered from some years ago when I was interested in such
a problem.

Usually, the tutors are better able to help if you post some initial
code and explain what you're trying to do and what is going wrong or
what you don't understand.



From alan.gauld at yahoo.co.uk  Mon Aug 14 11:55:39 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 14 Aug 2017 16:55:39 +0100
Subject: [Tutor] "Path tree"
In-Reply-To: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
References: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
Message-ID: <omsh5k$alu$1@blaine.gmane.org>

On 13/08/17 21:07, Michael C wrote:

> Please look at the picture attached: 

This is a text mailing list, no binary attachments allowed.
The server strips them off.

You need to put it on a web site and provide a link.


> consisting of (x,y).  Now I am trying to make a function go through this
> list of tuples and then return the "path." to go from, say, 4 to 8.

> How do I do this?

Do you know how to do it mathematically - eg with pen and paper?
If so its a matter of transcribing the algorithm into python
code. But if you don't know the background math, that's
where you need to start. Find the algorithm first.



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



From bandagunda at hotmail.com  Mon Aug 14 11:18:16 2017
From: bandagunda at hotmail.com (banda gunda)
Date: Mon, 14 Aug 2017 15:18:16 +0000
Subject: [Tutor] conditional renaming folder and files in the tree
In-Reply-To: <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
References: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>,
 <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <DB4PR06MB29774CAC94F216795013AC3DE8C0@DB4PR06MB297.eurprd06.prod.outlook.com>

Dear Tutor,


I have made some progress!

But not yet got the results.

Attached is revised code.


Specifically, the problem in below:


for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        print(os.path.join(root, name))
        os.rename(path + name, path + name.replace("---", "changed"))
        #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed")
        files[name] = os.sep.join([dirpath, name])

        print (files)

    for name in dirs:
        print(os.path.join(root, name))


.\---DAT1\---DAT3\---000010.txt


---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-6-316f0c967a9b> in <module>()
      2     for name in files:
      3         print(os.path.join(root, name))
----> 4         os.rename(path + name, path + name.replace("---", "changed"))
      5         #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed")
      6         files[name] = os.sep.join([dirpath, name])

FileNotFoundError: [WinError 2] The system cannot find the file specified: 'E://---000010.txt' -> 'E://changed000010.txt'


Thanks once again for your time spent on this.

best,
banda.
+

________________________________
From: banda gunda
Sent: Friday, August 11, 2017 8:10 AM
To: tutor at python.org
Subject: conditional renaming folder and files in the tree


Dear Tutor,

I want to change the name of the folders and the files in the tree.
All those folders and files starting with name string '---'.
Examples:
If a  folder name is : \---DAT1
I want to change this to: \changedDAT1
If a file name is: \---00001.txt
I want to change this to: \changed00001.txt

I have attached the code and output to this email.
Specifically, I like to provide correct syntax (dst / destination) for line 6 code block below!
I have not understood the syntax.

Thanks in advance, for your help .
best,
banda
+


for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        print(os.path.join(root, name))
        os.rename(name.replace("---", "changed"))
        list_of_files[name] = os.sep.join([dirpath, name])
        print (list_of_files)

    for name in dirs:
        print(os.path.join(root, name))


.\---DAT1\---00001.txt


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-b679212713d0> in <module>()
      2     for name in files:
      3         print(os.path.join(root, name))
----> 4         os.rename(name.replace("---", "changed"))
      5         list_of_files[name] = os.sep.join([dirpath, name])
      6         print (list_of_files)

TypeError: Required argument 'dst' (pos 2) not found

_end_of_email

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: file_folder_replace_name_strings_2.html
URL: <http://mail.python.org/pipermail/tutor/attachments/20170814/29e19782/attachment-0001.ksh>

From __peter__ at web.de  Mon Aug 14 12:47:36 2017
From: __peter__ at web.de (Peter Otten)
Date: Mon, 14 Aug 2017 18:47:36 +0200
Subject: [Tutor] conditional renaming folder and files in the tree
References: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>
 <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
 <DB4PR06MB29774CAC94F216795013AC3DE8C0@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <omsk74$anj$1@blaine.gmane.org>

banda gunda wrote:

> Dear Tutor,
> 
> 
> I have made some progress!
> 
> But not yet got the results.
> 
> Attached is revised code.
> 
> 
> Specifically, the problem in below:
> 
> 
> for root, dirs, files in os.walk(".", topdown=False):
>     for name in files:
>         print(os.path.join(root, name))
>         os.rename(path + name, path + name.replace("---", "changed"))

The `path` variable appears out of the blue here -- it should probably be 
`root`. Also, you should make it a habit to use os.path.join() to construct 
filenames, not string concatenation. The reason is that os.path.join() knows 
when to insert a path separator, and will pick the right one for the 
platform the script is running on.

>         #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---",
>         #"changed")

Do us (and yourself!) a favour, and remove abandoned code like the line 
above. It only makes the code harder to follow, and the one who suffers most 
from that are you. If you are afraid that you will lose valuable snippets 
put them elsewhere or consider adopting a version control system which 
allows you to go back to a former version when you find that a change was 
unsuccessful.

>         files[name] = os.sep.join([dirpath, name])

That doesn't make sense. What are you trying to achieve here?

> 
>         print (files)
> 
>     for name in dirs:
>         print(os.path.join(root, name))
> 
> 
> .\---DAT1\---DAT3\---000010.txt

Note that os.rename() can make a mess of your data. I recommend that you use 
print statements instead until you are sure that your script does what you 
want, something like

def dryrun_rename(old, new):
    print("rename", old)
    print("to    ", new)
    print()

for parent_dir, dirs, files in os.walk(".", topdown=False):
    for name in files:
        old_path = ... # construct filepath from parent_dir and name 
        new_path = ... # construct filepath from parent_dir and modified
                       # name
                       # use os.path.join in both cases
        dryrun_rename(old_path, new_path)

Once this prints what you expect you can swap dryrun_rename for os.rename.


From mats at wichmann.us  Mon Aug 14 12:55:31 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 14 Aug 2017 10:55:31 -0600
Subject: [Tutor] conditional renaming folder and files in the tree
In-Reply-To: <DB4PR06MB29774CAC94F216795013AC3DE8C0@DB4PR06MB297.eurprd06.prod.outlook.com>
References: <VI1PR06MB1054773006480A09A33D9271DE670@VI1PR06MB1054.eurprd06.prod.outlook.com>
 <DB4PR06MB2974157A51FB90B62048015DE890@DB4PR06MB297.eurprd06.prod.outlook.com>
 <DB4PR06MB29774CAC94F216795013AC3DE8C0@DB4PR06MB297.eurprd06.prod.outlook.com>
Message-ID: <26632134-7866-a4b9-eaea-d76f6515c186@wichmann.us>

On 08/14/2017 09:18 AM, banda gunda wrote:
> Dear Tutor,
> 
> 
> I have made some progress!
> 
> But not yet got the results.
> 
> Attached is revised code.
> 
> 
> Specifically, the problem in below:
> 
> 
> for root, dirs, files in os.walk(".", topdown=False):
>     for name in files:
>         print(os.path.join(root, name))
>         os.rename(path + name, path + name.replace("---", "changed"))
>         #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed")
>         files[name] = os.sep.join([dirpath, name])
> 
>         print (files)
> 
>     for name in dirs:
>         print(os.path.join(root, name))
> 
> 
> .\---DAT1\---DAT3\---000010.txt
> 
> 
> ---------------------------------------------------------------------------
> FileNotFoundError                         Traceback (most recent call last)
> <ipython-input-6-316f0c967a9b> in <module>()
>       2     for name in files:
>       3         print(os.path.join(root, name))
> ----> 4         os.rename(path + name, path + name.replace("---", "changed"))
>       5         #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed")
>       6         files[name] = os.sep.join([dirpath, name])
> 
> FileNotFoundError: [WinError 2] The system cannot find the file specified: 'E://---000010.txt' -> 'E://changed000010.txt'

Well, here are a few thoughts.

(1) it will really help if your debugging print in line 3 makes the same
path calculation as the command in line 4.  You can see these don't
match, which is a good hint you're getting something you don't expect.
(2) where are you getting "path" from?  It doesn't show in your code. Is
there any reason why you don't just use the same calculation as in line 3?
(3) for cautious programming, you can check if the file you are going to
rename exists (os.path.exists() or os.path.isfile()) before trying to
rename it, that would at least cause you not to take an exception and
quit when you get something wrong.
(4) you've still not fixed "dirpath" in line 6.  Note the python
documentation for the walk() function shows dirpath as the first element
of the result triple, but you've called it "root" in your code, so this
is probably what you meant.
(5) why are you printing the whole list of files in line 7? That means
you will show the files list each time you iterate through the list.
(6) it's usually not a great idea to modify an interable while you're
iterating over it (line 6).
(7) you indicate you want to rename the directories as well, but you are
not doing that.

From mysecretrobotfactory at gmail.com  Mon Aug 14 15:10:52 2017
From: mysecretrobotfactory at gmail.com (Michael C)
Date: Mon, 14 Aug 2017 12:10:52 -0700
Subject: [Tutor] "Path tree"
Message-ID: <CANyKM1gvy=SpoCigPTGZoZ7AQE0tYiyBVz=Jz7aWL8Q8LFv-4Q@mail.gmail.com>

http://imgur.com/a/CwA2G

I don't know to do this with math :(








On Sun, Aug 13, 2017 at 1:07 PM, Michael C <mysecretrobotfactory at gmail.com>
wrote:

> Hi all:
>
> I am trying to formulate a "path-finding" function, and I am stuck on this
> problem:
>
> Please look at the picture attached: Those dots are coordinates of (x,y),
> and this tree can be thought of as a list of tuples, with each tuple
> consisting of (x,y).  Now I am trying to make a function go through this
> list of tuples and then return the "path." to go from, say, 4 to 8. If I
> simply compute for the dot for shortest distance, then the solution would
> be to go from 4 to 8 direct, but that doesn't work, because the correct
> solution should have been 4,3,2,5,6,8.
>
>
> How do I do this?
>
> Thanks!
>

From alan.gauld at yahoo.co.uk  Mon Aug 14 17:06:54 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 14 Aug 2017 22:06:54 +0100
Subject: [Tutor] Fwd: Re:  "Path tree"
In-Reply-To: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
References: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
Message-ID: <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>


Forwarding to the list.

-------- Forwarded Message --------




pic
http://imgur.com/a/CwA2G

On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor <tutor at python.org
<mailto:tutor at python.org>> wrote:

    On 13/08/17 21:07, Michael C wrote:

    > Please look at the picture attached:

    This is a text mailing list, no binary attachments allowed.
    The server strips them off.

    You need to put it on a web site and provide a link.


    > consisting of (x,y).  Now I am trying to make a function go
    through this
    > list of tuples and then return the "path." to go from, say, 4 to 8.

    > How do I do this?

    Do you know how to do it mathematically - eg with pen and paper?
    If so its a matter of transcribing the algorithm into python
    code. But if you don't know the background math, that's
    where you need to start. Find the algorithm first.



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


    _______________________________________________
    Tutor maillist  -  Tutor at python.org <mailto:Tutor at python.org>
    To unsubscribe or change subscription options:
    https://mail.python.org/mailman/listinfo/tutor
    <https://mail.python.org/mailman/listinfo/tutor>



From mats at wichmann.us  Mon Aug 14 18:31:00 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 14 Aug 2017 16:31:00 -0600
Subject: [Tutor] Fwd: Re: "Path tree"
In-Reply-To: <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>
References: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
 <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>
Message-ID: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us>

On 08/14/2017 03:06 PM, Alan Gauld via Tutor wrote:
> 
> Forwarding to the list.
> 
> -------- Forwarded Message --------
> 
> 
> 
> 
> pic
> http://imgur.com/a/CwA2G
> 
> On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor <tutor at python.org
> <mailto:tutor at python.org>> wrote:
> 
>     On 13/08/17 21:07, Michael C wrote:
> 
>     > Please look at the picture attached:


So in modeling this in your program you need to describe not just the
x,y coordinates, but also the connections. point 1 can only reach point
2, so it has one link.  point 2 can reach 3 and 5, so two links. How can
you describe this in your data model?



From mysecretrobotfactory at gmail.com  Mon Aug 14 18:45:57 2017
From: mysecretrobotfactory at gmail.com (Michael C)
Date: Mon, 14 Aug 2017 15:45:57 -0700
Subject: [Tutor] Fwd: Re: "Path tree"
In-Reply-To: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us>
References: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
 <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>
 <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us>
Message-ID: <CANyKM1iqMtuBzjGdO7yGD1J5PqiGwXS6jZ3y4NGyOxE6ZgfT7w@mail.gmail.com>

I dont know what a data model is :(
I am thinking with one entry, I can have (x,y,z). Z is probably a list and
it says to what point it connects to. so it's a list of lists.
The problem then becomes: how do I generate a list of possible routes?
So I'll potentially have a very big list of routes and then I choose the
shortest one?



On Mon, Aug 14, 2017 at 3:31 PM, Mats Wichmann <mats at wichmann.us> wrote:

> On 08/14/2017 03:06 PM, Alan Gauld via Tutor wrote:
> >
> > Forwarding to the list.
> >
> > -------- Forwarded Message --------
> >
> >
> >
> >
> > pic
> > http://imgur.com/a/CwA2G
> >
> > On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor <tutor at python.org
> > <mailto:tutor at python.org>> wrote:
> >
> >     On 13/08/17 21:07, Michael C wrote:
> >
> >     > Please look at the picture attached:
>
>
> So in modeling this in your program you need to describe not just the
> x,y coordinates, but also the connections. point 1 can only reach point
> 2, so it has one link.  point 2 can reach 3 and 5, so two links. How can
> you describe this in your data model?
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From martin at linux-ip.net  Mon Aug 14 22:15:41 2017
From: martin at linux-ip.net (Martin A. Brown)
Date: Mon, 14 Aug 2017 19:15:41 -0700
Subject: [Tutor] Fwd: Re: "Path tree"
In-Reply-To: <CANyKM1iqMtuBzjGdO7yGD1J5PqiGwXS6jZ3y4NGyOxE6ZgfT7w@mail.gmail.com>
References: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
 <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>
 <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us>
 <CANyKM1iqMtuBzjGdO7yGD1J5PqiGwXS6jZ3y4NGyOxE6ZgfT7w@mail.gmail.com>
Message-ID: <alpine.LSU.2.11.1708141815070.31254@qnttre.jbaqresebt.arg>


Hello and good afternoon,

The image:

> http://imgur.com/a/CwA2G

To me, this looks like a 'graph', which is a more general data 
structure -- it does not look like a 'tree' (in the computer-science 
meaning of the term, anyway).

For purposes of all of my comments and answers below, I confess that 
I completely ignored the (x, y) in the image, because it seemed like 
every node ('dot') in your image was decorated with that.  See 
question(s) at the bottom of my message.

>> So in modeling this in your program you need to describe not just the
>> x,y coordinates, but also the connections. point 1 can only reach point
>> 2, so it has one link.  point 2 can reach 3 and 5, so two links.
>>
>> How can you describe this in your data model?

>I dont know what a data model is :(

'Data model' is a term to describe how you represent the world in 
your computer program.  Clearly, you have a question about the world 
and you want to use the computer to solve that question.  How do you 
do this?  Well, you create something in a computer language that 
tries to capture the important parts of the world for solving your 
problem.

Defining the data model in any problem is one of the great 
challenges of this game with computers that many of us play.  You 
gain experience simply by trying to solve problems.  (Sometimes, 
modelling the problem is harder than solving the problem.)

>I am thinking with one entry, I can have (x,y,z). Z is probably a 
>list and it says to what point it connects to. so it's a list of 
>lists. The problem then becomes: how do I generate a list of 
>possible routes? So I'll potentially have a very big list of routes 
>and then I choose the shortest one?

With your description of what you are looking to solve, my eye was 
drawn to the terms "list of possible routes" and "shortest [path]", 
it seems (that somebody has given you or) you have a classic graph 
problem.

>Please look at the picture attached: Those dots are coordinates of 
>(x,y), and this tree can be thought of as a list of tuples, with 
>each tuple consisting of (x,y).

I found this sentence the most confusing part of your description of 
the problem that you posted a day or two ago.  I'm still a bit 
confused, but if I ignore the above sentence entirely and focus on 
the rest of your questions, I think I know what you are asking.

<for_the_record>

Here are some things that confused me:

  * you used the word 'tree' which has a special meaning when 
    talking about data structures; a tree is a special form of 
    one class of graph
  * you used the word 'dots' because you were looking at a drawing 
    on a whiteboard, where many of us were thinking in more 
    abstract terms (well, I was, at least); so the word 'dots' meant 
    nothing to me until I saw your picture and realized that, to 
    you, these represented 'nodes' or 'vertices' (plural of 
    'vertex') in a 'graph' (data structure terminology)
  * you talked about 'coordinates' which suggests a measurable 
    geometric space -- I think you actually were trying to express 
    the notion of graph 'edges' (but I'm not sure! see below)

I was interested in your question (when you originally posted it), 
but couldn't figure out what you were actually trying to do and also 
did not understand what your real question was, so I would not have 
understood except that you posted the picture.

So, your follow-ups helped clarify that you are actually searching 
for data structure tools like the third-party graph library called 
networkx [0].

And, of course, I'll readily admit that sometimes expressing the 
problem in domain-specific or domain-relevant language is harder 
than solving the actual problem.

</for_the_record>

>Now I am trying to make a function go through this list of tuples 
>and then return the "path." to go from, say, 4 to 8. If I simply 
>compute for the dot for shortest distance, then the solution would 
>be to go from 4 to 8 direct, but that doesn't work, because the 
>correct solution should have been 4,3,2,5,6,8.

OK, so if the solution is 4,3,2,5,6,8, then your problem is a 
shortest path sort of graph theory problem and you can use the 
networkx library which has a huge number of tools for dealing with 
graphs (of many forms).

Below is a tailor-made example of how to model your picture in graph 
form using the networkx library.  My solution creates a data model 
representation of your graph (from your image) and then lists out 
the nodes ('dots'), the edges (lines connecting the dots) and then 
tries to find whether there's a path from node 4 to node 8.  Since 
there is a path from node 4 to node 8, it will print out the 
shortest such path.  You should recognize the answer:

Printed to STDOUT from my function below:

  Graph has nodes: [1, 2, 3, 4, 5, 6, 7, 8]
  Graph has edges: [(1, 2), (2, 3), (2, 5), (3, 4), (5, 6), (5, 7), (6, 8)]
  If there is a path in this graph from node 4 to node 8: True
  Path from 4 to 8: [4, 3, 2, 5, 6, 8]

>I am trying to formulate a "path-finding" function, and I am stuck 
>on this problem:

My main remaining questions:

  Why are you trying to find a path?
  What does the path (through this graph) tell you?
  What do (x, y) represent in that picture?

Good luck, Michael, in exploring Python for playing with graphs.  I 
think you may find that networkx will address almost anything you 
can throw at it for quite some time.  And, welcome to the Python 
world if you are new to it!

-Martin

 [0] https://networkx.github.io/


import networkx as nx


def solve_graph():
    g = nx.Graph()

    # -- my interpretation of http://i.imgur.com/MSq0p6z.png
    #    assumption:  not a tree
    #                 not a directed acyclic graph
    #                 not a directed graph
    #                 just a plain, undirected graph
    #
    description = [(1, 2), (2, 3), (3, 4), (2, 5), (5, 7), (5, 6), (6, 8)]
    g.add_edges_from(description)

    # -- nodes are also known as vertices in a graph
    #
    nodes = g.nodes()
    print("Graph has nodes: %r" % (nodes,))

    # -- the edges should be familiar -- identical to the above
    #
    edges = g.edges()
    print("Graph has edges: %r" % (edges,))

    # -- can you get to destination from source?
    source = 4
    destination = 8
    reachable = nx.has_path(g, source, destination)
    print("If there is a path in this graph from node %s to node %s: %s" %
          (source, destination, reachable,))

    # -- can you get to destination from source?
    if reachable:
        path = nx.shortest_path(g, source, destination)
        print("Path from %s to %s: %r" % (source, destination, path,))


-- 
Martin A. Brown
http://linux-ip.net/

From __peter__ at web.de  Tue Aug 15 03:10:39 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 15 Aug 2017 09:10:39 +0200
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <omp3vt$m9s$1@blaine.gmane.org>
 <CANDiX9KxMfyHAAVOqpuq5kUFBRYPk_HMxF3WnyEF=dRBT_4p8w@mail.gmail.com>
Message-ID: <omu7bv$cvc$1@blaine.gmane.org>

boB Stepp wrote:

> On Sun, Aug 13, 2017 at 3:52 AM, Peter Otten <__peter__ at web.de> wrote:
>> boB Stepp wrote:

>> Still, a good unit test might be to initialise a RatingCalcultator with
>> different "highest possible ratings" and then verify for each instance
>> that actual ratings never exceed the specified value.
> 
> I just had not gotten around to doing this yet.

>> If there are no hard limits, why give a limit at all?
> 
> My thinking was to put in a sanity check.  The ratings should fall
> into sensible limits.

>>>     _LOWEST_POSSIBLE_RATING = 0
>>
>> Again, this is just a number. Is it really worthwile explicit checking in
>> a unit test? The most relevant tests address behaviour.
> 
> Shouldn't I check for inadvertent changing of what are constants by
> later modifications of the code?

In what scenario would such an inadvertent change occur?

I prefer the indirect check sketched out above. Assuming there is a 
check_rating() method you can make tests like

rc = RatingCalculator(lowest_rating=0, highest_rating=100)
for r in [0, 50, 100]:
    rc.check_rating(r)
for r in [-1, 101]:
    with self.assertRaises(FailedSanityCheck):
        rc.check_rating(101)

that ensure that a method works as expected rather than verifying a certain 
constant value. (You have to do the above for at least two ranges to make 
sure that the arguments are used for the check.)


> 
>>>     _HIGHEST_POSSIBLE_RATING = 3000
>>>
>>>     # Fundamental constants for use in the chess rating formula.  The
>>>     # keys to these values are tuples giving the rating ranges for which
>>>     # these K-factors are valid.
>>>
>>>     _K_MULTIPLIERS = {
>>>             (_LOWEST_POSSIBLE_RATING, 2099): 0.04,
>>
>> The Python way uses half-open intervals. This has the advantage that
>> there is a well-defined k-multiplier for a rating of 2099.5. Note that if
>> you apply that modification you no longer need any upper limits. Use
>> bisect (for only threee values linear search is OK, too) to find the
>> interval from a list like [0, 2100, 2400], then look up the multiplier in
>> a second list
>> [0.04, 0.03, 0.02])
> 
> Note:  Valid ratings can only be positive integers.  No floats allowed
> in the final rating result or in the initial input of an established
> rating that is to be changed.

Then you need a test for that ;)
 
> So you are suggesting doing something like:

> py3: from bisect import bisect
> py3: def get_k_factors(rating):

Yes, but I would pass the lists as arguments to allow for easier testing.

> ...     RATING_BREAKPOINTS = [0, 2100, 2400]
> ...     K_ADDERS = [16, 12, 8]
> ...     K_MULTIPLIERS = [0.04, 0.03, 0.02]
> ...     index = bisect(RATING_BREAKPOINTS, rating) - 1
> ...     k_adder = K_ADDERS[index]
> ...     k_multiplier = K_MULTIPLIERS[index]
> ...     return k_adder, k_multiplier
> ...

>> With the _ you are making these constants implementation details. Isn't
>> one goal of unit tests to *allow* for changes in the implementation while
>> keeping the public interface?
> 
> I don't think I am understanding your thoughts.  Would you please
> provide an illustrative example?  

When you are sending a parcel to a friend you don't care about the path it 
takes or that the delivery service obeys the speed limit. You only demand 
that it arrives at the specified place within the specified time interval.
That way the service is free to choose the best (quickest, shortest, or 
cheapest) route and the best (fastest, cheapest) means of transportation.

A class is a service provider, too. If you test private methods and states 
you are either stuck with one implementation or have to change unit tests 
and implementation in lockstep -- and these unit test modifications may 
introduce bugs, too.

If instead you manage to cover the code with tests that only use the public 
interface you can replace one implementation of the tested class with a 
completely different one -- and when your unit tests continue to succeed you 
are pretty sure that the replacement is correct, too. 

Thus the hurdle to trying out improvements ("refactoring") is lower and you 
are more likely to end up with clean and efficient code.

> I am concerned that later program
> development or maintenance might inadvertently alter values that are
> expected to be constants.

Unlike 0 the value of 3000 is in no way special. Your script will be more 
robust if it continues to work with an upper bound of 2900 or 4000 -- or 
even floats in the range 0 <= rating < 1.

>> Values are the most volatile and least important part of a program.
>> Start coding with the algorithms and tests covering those.
> 
> I was just looking for the lowest hanging fruit to get an easy start
> on this project, and use it as a check to see if I was going off in
> inadvisable directions.

I think that is mostly a distraction. 

Unfortunately there are many ways to burn time dealing with the irrelevant 
aspects of a program. I know some of them -- from hearsay, of course ;)


From __peter__ at web.de  Tue Aug 15 03:56:44 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 15 Aug 2017 09:56:44 +0200
Subject: [Tutor] "Path tree"
References: <CANyKM1jUWJswbikoN1H+d2tbx-gz60pA1roGPVy-HUNnJduiog@mail.gmail.com>
 <cd49726c-0677-0532-5ef6-ac1d47f130ef@yahoo.co.uk>
 <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us>
 <CANyKM1iqMtuBzjGdO7yGD1J5PqiGwXS6jZ3y4NGyOxE6ZgfT7w@mail.gmail.com>
 <alpine.LSU.2.11.1708141815070.31254@qnttre.jbaqresebt.arg>
Message-ID: <omudnr$bh3$1@blaine.gmane.org>

Martin A. Brown wrote:

> The image:
> 
>> http://imgur.com/a/CwA2G
> 
> To me, this looks like a 'graph', which is a more general data
> structure -- it does not look like a 'tree' (in the computer-science
> meaning of the term, anyway).

> import networkx as nx

While Martin's solution is certainly more robust it may also be instructive 
to see it done "by hand":

edges = [
    (1, 2),
    (2, 5),
    (2, 3),
    (3, 4),
    (5, 7),
    (5, 6),
    (6, 8),
# remove the comment to see what happens 
# when there is more than one path between two nodes
#    (1, 8), 
]

graph = {}

# make a lookup table node --> neighbours
for a, b in edges:
    graph.setdefault(a, []).append(b)
    graph.setdefault(b, []).append(a)
print(graph)

def connect(start, end, path, graph):
    path += (start,)
    if start == end:
        # we found a connection
        yield path
    neighbours = graph[start]

    # try all neighbours, but avoid cycles to nodes already in the path
    for node in neighbours:
        if node not in path:
            # recurse to find connection from neigbour to end
            yield from connect(node, end, path, graph)

for path in connect(4, 8, (), graph):
    print(path)


From neilc at norwich.edu  Tue Aug 15 10:09:13 2017
From: neilc at norwich.edu (Neil Cerutti)
Date: Tue, 15 Aug 2017 14:09:13 +0000 (UTC)
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
Message-ID: <omuva9$tj7$1@blaine.gmane.org>

On 2017-08-13, boB Stepp <robertvstepp at gmail.com> wrote:
> REPORT GENERATION
>
> There are a variety of reports that I would like to be able to
> print to screen or paper.  Things such as a "Top x List" of
> rated players, full rating list sorted from highest rating to
> lowest, rating lists for the current school year only or a
> particular past school year, and so.  I could see wanting to
> sort such lists by various criteria depending on the type of
> report I would like to generate.  Currently this section of the
> program is a big gray area for me, but I see no reason why my
> two dictionaries cannot be manipulated to pull the desired
> results for each imagined type of report.

You really can do it, but to me this requirement argues for going
back to a database backend. Why rewrite SQL?

-- 
Neil Cerutti


From alan.gauld at yahoo.co.uk  Tue Aug 15 13:29:38 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 15 Aug 2017 18:29:38 +0100
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <omuva9$tj7$1@blaine.gmane.org>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
 <omuva9$tj7$1@blaine.gmane.org>
Message-ID: <omvb1r$jiu$1@blaine.gmane.org>

On 15/08/17 15:09, Neil Cerutti wrote:

>> There are a variety of reports that I would like to be able to
>> print to screen or paper.  Things such as a "Top x List" of
>> rated players, full rating list sorted from highest rating to
>> lowest, rating lists for the current school year only or a
>> particular past school year, and so.  ...

> You really can do it, but to me this requirement argues for going
> back to a database backend. Why rewrite SQL?

I agree with Neil, this is exactly what SQL is good for and
would make this part of the project much easier and would have
the added benefit of introducing you to one of the trickiest,
but most common, bits of OOP - object persistence...

You might even find yourself writing some class methods! ;-)

And using SQLite, (even using in-memory mode if you don't
want to keep a database file) is about as easy as SQL gets.

If you do want to do it by hand consider using the itertools
module. (eg. its filterfalse(), dropwhile()/takewhile()
combinations() and groupby() functions.)

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



From cs at cskk.id.au  Tue Aug 15 21:02:23 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 16 Aug 2017 11:02:23 +1000
Subject: [Tutor] "Path tree"
In-Reply-To: <CANyKM1gvy=SpoCigPTGZoZ7AQE0tYiyBVz=Jz7aWL8Q8LFv-4Q@mail.gmail.com>
References: <CANyKM1gvy=SpoCigPTGZoZ7AQE0tYiyBVz=Jz7aWL8Q8LFv-4Q@mail.gmail.com>
Message-ID: <20170816010223.GA98601@cskk.homeip.net>

On 14Aug2017 12:10, Michael C <mysecretrobotfactory at gmail.com> wrote:
>http://imgur.com/a/CwA2G

Ok. So you have a graph like this:

  1 -- 2 -- 3 -- 4
       |
  7 -- 5 -- 6 -- 8

Have a read of a graph theory textbook. Also, wikipedia has an article on 
finding the shortest path through a graph:

  https://en.wikipedia.org/wiki/Shortest_path_problem

which references several algorithms.

You could pick one (eg Dijkstra's algorithm) and try to implement it. For a 
graph this small you could try your own and do something rather brute force; in 
larger graphs efficiency becomes very important.

You will need to express the graph as a data structure in your code, with a 
data structure that expresses which nodes connect to each other node. Typically 
this often includes weights for the edges and a direction, but your graph has 
no weights (cost of traversing a particular edge) and is undirected (you can 
traverse an edge in either direction). It is also "simply connected" - there 
are no loops. All these things make your task simpler.

You can express a graph as a direcionary with keys being your node numbers 
(i.e. 1, 2, 3 etc) and the values being a list of the other nodes to which each 
connects. Eg:

  graph = {
    1: [2],
    2: [1, 3],
    3: [2, 4],
    4: [3],
    5: [7, 6],
    6: [5, 8],
    7: [5],
    8: [6]
  }

The you need to write code that starts somewhere (4 in your example) and moves 
to other nodes until it reaches the target node (8 in your example). You can 
see which other nodes are reachable your current from the dictionary above. You 
need to keep some kind of record of which nodes you have visted (i.e. that is 
the path).

See if that gets you started. For debugging, make your program print out what 
node it is at as it traverses the graph - that will be helpful to you in 
figuring out what is working and what is not.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From robertvstepp at gmail.com  Tue Aug 15 23:06:26 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 15 Aug 2017 22:06:26 -0500
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <omvb1r$jiu$1@blaine.gmane.org>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
 <omuva9$tj7$1@blaine.gmane.org> <omvb1r$jiu$1@blaine.gmane.org>
Message-ID: <CANDiX9Lc-Lt-xQ8-EBwaY+FyxFKbZNaLinMMu1Hji4Rnu4WPCg@mail.gmail.com>

On Tue, Aug 15, 2017 at 12:29 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 15/08/17 15:09, Neil Cerutti wrote:
>
>>> There are a variety of reports that I would like to be able to
>>> print to screen or paper.  Things such as a "Top x List" of
>>> rated players, full rating list sorted from highest rating to
>>> lowest, rating lists for the current school year only or a
>>> particular past school year, and so.  ...
>
>> You really can do it, but to me this requirement argues for going
>> back to a database backend. Why rewrite SQL?

I just thought this would be an interesting problem type to tackle.
No intentions of reinventing SQL!

> I agree with Neil, this is exactly what SQL is good for and
> would make this part of the project much easier and would have
> the added benefit of introducing you to one of the trickiest,
> but most common, bits of OOP - object persistence...

Would you expand on this in SQLite terms?

> You might even find yourself writing some class methods! ;-)

Nah.  I might expand my array of constants, and test a few more ... ~(:>))



-- 
boB

From alan.gauld at yahoo.co.uk  Wed Aug 16 05:16:45 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 16 Aug 2017 10:16:45 +0100
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
In-Reply-To: <CANDiX9Lc-Lt-xQ8-EBwaY+FyxFKbZNaLinMMu1Hji4Rnu4WPCg@mail.gmail.com>
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
 <omuva9$tj7$1@blaine.gmane.org> <omvb1r$jiu$1@blaine.gmane.org>
 <CANDiX9Lc-Lt-xQ8-EBwaY+FyxFKbZNaLinMMu1Hji4Rnu4WPCg@mail.gmail.com>
Message-ID: <on12hm$cm$1@blaine.gmane.org>

On 16/08/17 04:06, boB Stepp wrote:

>> I agree with Neil, this is exactly what SQL is good for and
>> would make this part of the project much easier and would have
>> the added benefit of introducing you to one of the trickiest,
>> but most common, bits of OOP - object persistence...
> 
> Would you expand on this in SQLite terms?

I'm not sure which bit you want expanded so I'll do both :-)

The reporting side is easily within SQLite's capabilities
once you have the table structures defined. And SQLite's
big benefit for this kind of project is that there is
no server involved just a single data file, so easy
to maintain. You can even use the in-memory mode if you
just want the SQL aspects and are happy to persist
your objects in text files(JSON maybe?) Simply load
the JSON data into SQLite in-memory tables to perform
the queries.

The persistence issue really has nothing to do with
SQLite per se. To persist (ie store) your objects
between program runs requires that you save them
to disk somehow. Simple classes can be saved in
simple text files. but as classes contain other
classes/objects that gets complex. The next step
is a formatted storage mechanism like XML or JSON
which can handle nested objects. The other issue
in persistence is when to save the objects? Do
you just load everything into memory at startup and
then write it all back at shutdown? Or do you
incrementally save all changes as they happen?
In a dynamic, garbage collecting language like
Python incremental saves are safer in case an
object gets deleted accidentally, before it is saved.

But sooner or later you will need to move to a database
and that brings the issues of translating a class
into tables - especially if inheritance is involved.
Do you have a table per class with superclass links?
Or do you duplicate the  superclass attributes in
each child table? There are no right answers and
figuring out the most effective mapping is one of
the big challenges in real world OOP projects.

Another option is to adopt an Object Relational
Mapper (ORM) which will create and manage the SQL
aspects for you - but in the process make reporting
more difficult.

And lastly you could use a NoSQL database like Mongo
which can more easily persist complex objects and has
a reasonable reporting language (especially if you
use Mongoose). But this is likely a much bigger learning
curve, especially if its the first time you've used
it.

For your project I suspect a JSON solution would
be fine for persistence but no help for reporting.
SQLite, especially if you don't have lots of
complex classes, gives both for low cost (both
resources and learning) assuming you know basic
SQL to start with.

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



From alan.gauld at yahoo.co.uk  Wed Aug 16 05:22:12 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 16 Aug 2017 10:22:12 +0100
Subject: [Tutor] "Path tree"
In-Reply-To: <20170816010223.GA98601@cskk.homeip.net>
References: <CANyKM1gvy=SpoCigPTGZoZ7AQE0tYiyBVz=Jz7aWL8Q8LFv-4Q@mail.gmail.com>
 <20170816010223.GA98601@cskk.homeip.net>
Message-ID: <on12rt$3hu$1@blaine.gmane.org>

On 16/08/17 02:02, Cameron Simpson wrote:

> Ok. So you have a graph like this:

>   1 -- 2 -- 3 -- 4
>        |
>   7 -- 5 -- 6 -- 8
> 
>   graph = {
>     1: [2],
>     2: [1, 3],

      2: [1, 3, 5],

>     3: [2, 4],
>     4: [3],
>     5: [7, 6],

      5: [2, 6, 7],

>     6: [5, 8],
>     7: [5],
>     8: [6]
>   }

The missing link is pretty critical in this case :-)

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



From jcquantz1 at gmail.com  Wed Aug 16 12:33:05 2017
From: jcquantz1 at gmail.com (Quantz Jeremy)
Date: Wed, 16 Aug 2017 10:33:05 -0600
Subject: [Tutor] pygame not working
Message-ID: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>

I?m not sure if I should be asking here about this, but on my Mac computer, Pygame keeps crashing on me. I have Python 2.7.13 (I can?t use Python 3 because I?m learning from and online course and he?s using Python 2.7.13. Unless you can give me a list or something for all the differences, I am completely new to Python, and a beginner programer.) Mac OS X 32-bit i386/PPC installer. I got my version of Pygame from Pygame.org <http://pygame.org/>, I downloaded the pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg <http://pygame.org/ftp/pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg>. It?s working until I actually try to draw anything on my screen. For example, I can run the following code and it works just fine.

import pygame

pygame.init()
screen = pygame.display.set_mode((900,700))

finished = False

while finished == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            finished = True

But when I run the following code, the Pygame window opens for a split second, then closes and I get a message from my Mac saying Python (My pygame window, not Python IDLE) quit unexpectedly. I?ve looked to see where it crashes and it?s when it reaches where it?s suppose to draw the rectangle. I can?t even see the rectangle for the split second while it?s open. (which if it crashes at that part, it makes sense.) 

import pygame

pygame.init()
screen = pygame.display.set_mode((900,700))

finished = False

while finished == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            finished = True
    
    rectOne = pygame.Rect(0,0,800,450)
    
    color = (0,0,255) #R,G,B
    pygame.draw.rect(screen,color,rectOne)
    pygame.display.flip()

I?ll try and give you as much info about my Mac as I can, as I think it?s the computer itself that?s the problem. But if you can?t help me, I do have a windows 10 laptop that I?ve tried putting Pygame on that we could see if you could help me put Pygame on that. I can?t seem to get the right one. I?d rather it on the Mac. I have tried many tutorials as well and nothing is working. I have a 2010 iMac (Old I know) with a 3.06 GHz Intel Core i3 Processor. Graphics are ATI Radeon HD 4670 256 MB. My OS Is X El Capitan Version 10.11.6. I don?t know what of that info you need, or if you need more, but that?s about it. If you could please help me with my problem, it would be much appreciated. I already tried stack overflow, and that didn?t work. I also think it is the computer because someone on there ran my code and it worked just fine. Thanks.
~Ethan

From alan.gauld at yahoo.co.uk  Wed Aug 16 14:24:58 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 16 Aug 2017 19:24:58 +0100
Subject: [Tutor] pygame not working
In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
Message-ID: <on22li$iq1$1@blaine.gmane.org>

On 16/08/17 17:33, Quantz Jeremy wrote:
> I?m not sure if I should be asking here about this,

Strictly speaking no, this list is for questions about
Python and its standard library. So PyGame issues should
really go to the PyGame support fora, and that's still
the best place for detailed support. Here's the top
level link:

http://www.pygame.org/wiki/info?parent=

The getting started page is worth reading too if you
haven't already.

But...

>  ...I have Python 2.7.13 ...Mac OS X 32-bit i386/PPC installer. 

Because you've given us so much detail there's a fair
chance somebody here will try and help.

You shouldn't need to go to Windows, the Mac version should
be fine. OTOH the windows version of pyGame should be
fine too!

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



From robertvstepp at gmail.com  Wed Aug 16 16:14:20 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 16 Aug 2017 15:14:20 -0500
Subject: [Tutor] pygame not working
In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
Message-ID: <CANDiX9JaqSusWRn2sykKLhVmTk8a4ZFjB0tvqNNnG0Q2_vW_ww@mail.gmail.com>

On Wed, Aug 16, 2017 at 11:33 AM, Quantz Jeremy <jcquantz1 at gmail.com> wrote:
> I?m not sure if I should be asking here about this, but on my Mac computer, Pygame keeps crashing on me. I have Python 2.7.13 (I can?t use Python 3 because I?m learning from and online course and he?s using Python 2.7.13. Unless you can give me a list or something for all the differences, I am completely new to Python, and a beginner programer.) Mac OS X 32-bit i386/PPC installer. I got my version of Pygame from Pygame.org <http://pygame.org/>, I downloaded the pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg <http://pygame.org/ftp/pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg>. It?s working until I actually try to draw anything on my screen. For example, I can run the following code and it works just fine.

[snip]

> But when I run the following code, the Pygame window opens for a split second, then closes and I get a message from my Mac saying Python (My pygame window, not Python IDLE) quit unexpectedly. I?ve looked to see where it crashes and it?s when it reaches where it?s suppose to draw the rectangle. I can?t even see the rectangle for the split second while it?s open. (which if it crashes at that part, it makes sense.)
>

[snip]

> I?ll try and give you as much info about my Mac as I can, as I think it?s the computer itself that?s the problem. But if you can?t help me, I do have a windows 10 laptop that I?ve tried putting Pygame on that we could see if you could help me put Pygame on that. I can?t seem to get the right one. I?d rather it on the Mac. I have tried many tutorials as well and nothing is working. I have a 2010 iMac (Old I know) with a 3.06 GHz Intel Core i3 Processor. Graphics are ATI Radeon HD 4670 256 MB. My OS Is X El Capitan Version 10.11.6. I don?t know what of that info you need, or if you need more, but that?s about it. If you could please help me with my problem, it would be much appreciated. I already tried stack overflow, and that didn?t work. I also think it is the computer because someone on there ran my code and it worked just fine. Thanks.

I did a quick search and a couple of things came up that *might* be
related to your issue (I am *not* an expert in programming!).  One
thing that came up is that if you are running IDLE, which relies on
Tkinter, and pygame at the same time, they both try to run their own
event loops and this can cause conflicts.  Are you starting your
pygame program from within IDLE?  If yes, you may want to instead
start your program from within the terminal window.  The other is are
you sure that your program is running with the version of Python you
think it is?  If you installed a later version of Python 2 yourself
you may in fact be running an older version of Python 2 with your
program, the one supplied originally with your Mac which is the system
default.  But I am just guessing here!


-- 
boB

From cs at cskk.id.au  Wed Aug 16 18:36:21 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Thu, 17 Aug 2017 08:36:21 +1000
Subject: [Tutor] "Path tree"
In-Reply-To: <on12rt$3hu$1@blaine.gmane.org>
References: <on12rt$3hu$1@blaine.gmane.org>
Message-ID: <20170816223621.GA47401@cskk.homeip.net>

On 16Aug2017 10:22, Alan Gauld <alan.gauld at yahoo.co.uk> wrote:
>On 16/08/17 02:02, Cameron Simpson wrote:
>> Ok. So you have a graph like this:
>
>>   1 -- 2 -- 3 -- 4
>>        |
>>   7 -- 5 -- 6 -- 8
>>
>>   graph = {
>>     1: [2],
>>     2: [1, 3],
>
>      2: [1, 3, 5],
>
>>     3: [2, 4],
>>     4: [3],
>>     5: [7, 6],
>
>      5: [2, 6, 7],
>
>>     6: [5, 8],
>>     7: [5],
>>     8: [6]
>>   }
>
>The missing link is pretty critical in this case :-)

Hmm, yes. Thanks!

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From steve at pearwood.info  Wed Aug 16 20:13:39 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 17 Aug 2017 10:13:39 +1000
Subject: [Tutor] pygame not working
In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
Message-ID: <20170817001339.GR7395@ando.pearwood.info>

Hi Quantz Jeremy, or Ethan, which do you prefer?

On Wed, Aug 16, 2017 at 10:33:05AM -0600, Quantz Jeremy wrote:

> I already tried stack overflow, and that didn?t work.

What did you ask, and what answers did they give that didn't work? Or is 
it a secret? :-)



-- 
Steve

From 1019shaun at gmail.com  Wed Aug 16 18:36:51 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Wed, 16 Aug 2017 15:36:51 -0700
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
References: <CAG0JesjL-a5yW=gJ++5-mcs7xP3-y=m-ZgLqPdVBwrXkQ4thoA@mail.gmail.com>
 <CAG0JesgynYsQSk_Y0tvZRBG44UW2SH2rVvxegwOB3pYs7p3QOA@mail.gmail.com>
 <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
Message-ID: <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>

class Address:
        def _init_(self,Hs,St,Town,Zip):
                      self.HsNunber=Hs
                      self.Street=St
                      self.Town=Town
                      self.Zip=Zip
Addr=Address (7, ' high st', 'anytown', ' 123 456')


Traceback (most recent call last):
File "<pyshell#151>", line 1, in< module>
Addr = Address (7, 'High St', 'anytown', '123 456')
TypeError: object () takes no parameters

 how to fix this and where I went wrong

 This happened to me in other coding
But I skipped it,but it keeps returning!
This is from a tutorial

From 1019shaun at gmail.com  Wed Aug 16 20:08:47 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Wed, 16 Aug 2017 17:08:47 -0700
Subject: [Tutor] Object takes no parameters
In-Reply-To: <CAG0Jesg_GMFrwCOdwvcp9pqbw=3E2SfeuJhWxmdhm0QxdwgCpA@mail.gmail.com>
References: <CAG0Jesg_GMFrwCOdwvcp9pqbw=3E2SfeuJhWxmdhm0QxdwgCpA@mail.gmail.com>
Message-ID: <CAG0JesjgpNNJ1aWyiSuWzDg9iYtS4E64Sa_xcdzHKKGv7z0NbQ@mail.gmail.com>

class Human:
     def _init_(self, n, o)
          self.name = n
          self.occupation = o

     def do_work(self):
         if self.occupation== 'tennis player':
            print(self.name, 'plays tennis')

         elif self.occupation == 'actor':
            print(self.name, 'shoots film')

     def speaks(self):
         print(self.name, 'how are you')

tom = Human('tom cruise', 'actor')
tom.do_work()
tom.speak()

Traceback most recent call last
File "c:\users\shaun\python\python35\human_class.py"line 16 in module
tom =Human('tom cruise', 'actor')
TypeError: object() takes no parameters

how to fix this?why it happens?
this happens whenever i try to do
class,this is from a tutorial

From zachary.ware+pytut at gmail.com  Wed Aug 16 21:02:23 2017
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Wed, 16 Aug 2017 20:02:23 -0500
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
References: <CAG0JesjL-a5yW=gJ++5-mcs7xP3-y=m-ZgLqPdVBwrXkQ4thoA@mail.gmail.com>
 <CAG0JesgynYsQSk_Y0tvZRBG44UW2SH2rVvxegwOB3pYs7p3QOA@mail.gmail.com>
 <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
 <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
Message-ID: <CAKJDb-NDDC-9HwnDcjx9_4sFvKNue=_9ourgcjtsDNvTSnfiAg@mail.gmail.com>

Hi Howard,

On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com> wrote:
> class Address:
>         def _init_(self,Hs,St,Town,Zip):

Your issue is in this line, it should be `__init__` rather than
`_init_` (that is, two underscores before and after "init").

Hope this helps,
-- 
Zach

From alan.gauld at yahoo.co.uk  Wed Aug 16 21:11:43 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 17 Aug 2017 02:11:43 +0100
Subject: [Tutor] Object takes no parameters
In-Reply-To: <CAG0JesjgpNNJ1aWyiSuWzDg9iYtS4E64Sa_xcdzHKKGv7z0NbQ@mail.gmail.com>
References: <CAG0Jesg_GMFrwCOdwvcp9pqbw=3E2SfeuJhWxmdhm0QxdwgCpA@mail.gmail.com>
 <CAG0JesjgpNNJ1aWyiSuWzDg9iYtS4E64Sa_xcdzHKKGv7z0NbQ@mail.gmail.com>
Message-ID: <on2qg7$spt$1@blaine.gmane.org>

On 17/08/17 01:08, Howard Lawrence wrote:
> class Human:
>      def _init_(self, n, o)
>           self.name = n
>           self.occupation = o
> 

> 
> tom = Human('tom cruise', 'actor')
> 
> Traceback most recent call last
> File "c:\users\shaun\python\python35\human_class.py"line 16 in module
> tom =Human('tom cruise', 'actor')
> TypeError: object() takes no parameters
> 
> how to fix this?why it happens?

If you look closely at your tutorial you will find that init()
has two underscores before and after the name:

def __init__()

rather than

def _init_()

The reason for your error is that all classes inherit from object.
So when you call Human() the interpreter looks for an __init__()
method and, not finding one(because yours only has one undercore),
it looks at the one defined in object. But the object init()
takes no parameters and so there is a mismatch between your
call to Human() and the object.__init__() definition.
Hence the error message.

To fix it use two underscores.

All of the "magic" methods used by Python have these double
underscores and  hence are often referred to as "dunder" methods.
You should avoid defining any new methods (ie new names) with
double underscores yourself, in case Python introduces  a
similar method in a future version.

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



From alan.gauld at yahoo.co.uk  Wed Aug 16 21:16:19 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 17 Aug 2017 02:16:19 +0100
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
References: <CAG0JesjL-a5yW=gJ++5-mcs7xP3-y=m-ZgLqPdVBwrXkQ4thoA@mail.gmail.com>
 <CAG0JesgynYsQSk_Y0tvZRBG44UW2SH2rVvxegwOB3pYs7p3QOA@mail.gmail.com>
 <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
 <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
Message-ID: <on2qos$j1c$1@blaine.gmane.org>

On 16/08/17 23:36, Howard Lawrence wrote:
> class Address:
>         def _init_(self,Hs,St,Town,Zip):
>                       self.HsNunber=Hs
>                       self.Street=St
>                       self.Town=Town
>                       self.Zip=Zip
> Addr=Address (7, ' high st', 'anytown', ' 123 456')

That looks suspiciously like my tutorial ;-)

The answer is to use two underscores around init():

def __init__(...)

not

def _init_(...)

This is explained in more detail in a box at the end
of the data topic:

http://www.alan-g.me.uk/l2p/tutdata.htm

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



From arj.python at gmail.com  Wed Aug 16 23:22:08 2017
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Thu, 17 Aug 2017 07:22:08 +0400
Subject: [Tutor] "Path tree"
In-Reply-To: <CADrxXXn7a1sY=GQ=RAnggu8sQSkZi5aDs-VembOTPGsA1mtdKg@mail.gmail.com>
References: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
 <CADrxXXn7a1sY=GQ=RAnggu8sQSkZi5aDs-VembOTPGsA1mtdKg@mail.gmail.com>
Message-ID: <CADrxXXmUs3aBQ6CAM5gfF5eHy989uaD+3zujjMV2UA6_x=FBxw@mail.gmail.com>

in addition to the answers i'd say now you have the motivation to learn
python data structures and algorithms

http://interactivepython.org/runestone/static/pythonds/index.html

barnum and miller

it is free though i have not found a good pdf book form from where to
download, but you have the site anyway !

Now, the website has more materials than when i first knew it.

hope it helps !

Abdur-Rahmaan Janhangeer,
Mauritius
abdurrahmaanjanhangeer.wordpress.com

On 14 Aug 2017 02:28, "Michael C" <mysecretrobotfactory at gmail.com> wrote:

Hi all:

I am trying to formulate a "path-finding" function, and I am stuck on this
problem:

Please look at the picture attached: Those dots are coordinates of (x,y),
and this tree can be thought of as a list of tuples, with each tuple
consisting of (x,y).  Now I am trying to make a function go through this
list of tuples and then return the "path." to go from, say, 4 to 8. If I
simply compute for the dot for shortest distance, then the solution would
be to go from 4 to 8 direct, but that doesn't work, because the correct
solution should have been 4,3,2,5,6,8.


How do I do this?

Thanks!
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

From mysecretrobotfactory at gmail.com  Wed Aug 16 23:23:35 2017
From: mysecretrobotfactory at gmail.com (Michael C)
Date: Wed, 16 Aug 2017 20:23:35 -0700
Subject: [Tutor] "Path tree"
In-Reply-To: <CADrxXXmUs3aBQ6CAM5gfF5eHy989uaD+3zujjMV2UA6_x=FBxw@mail.gmail.com>
References: <CANyKM1g2vs==rZwUGBL=5n2hjdEV-tfwgEq-N2Az3e0XRiNtgg@mail.gmail.com>
 <CADrxXXn7a1sY=GQ=RAnggu8sQSkZi5aDs-VembOTPGsA1mtdKg@mail.gmail.com>
 <CADrxXXmUs3aBQ6CAM5gfF5eHy989uaD+3zujjMV2UA6_x=FBxw@mail.gmail.com>
Message-ID: <CANyKM1jJE6O6H_Ebceb_Mk0fwL_zffzvDcBdFqPdE63w-m3ZCg@mail.gmail.com>

Ok, I will work with all these. Thx all!

On Aug 16, 2017 20:22, "Abdur-Rahmaan Janhangeer" <arj.python at gmail.com>
wrote:

> in addition to the answers i'd say now you have the motivation to learn
> python data structures and algorithms
>
> http://interactivepython.org/runestone/static/pythonds/index.html
>
> barnum and miller
>
> it is free though i have not found a good pdf book form from where to
> download, but you have the site anyway !
>
> Now, the website has more materials than when i first knew it.
>
> hope it helps !
>
> Abdur-Rahmaan Janhangeer,
> Mauritius
> abdurrahmaanjanhangeer.wordpress.com
>
> On 14 Aug 2017 02:28, "Michael C" <mysecretrobotfactory at gmail.com> wrote:
>
> Hi all:
>
> I am trying to formulate a "path-finding" function, and I am stuck on this
> problem:
>
> Please look at the picture attached: Those dots are coordinates of (x,y),
> and this tree can be thought of as a list of tuples, with each tuple
> consisting of (x,y).  Now I am trying to make a function go through this
> list of tuples and then return the "path." to go from, say, 4 to 8. If I
> simply compute for the dot for shortest distance, then the solution would
> be to go from 4 to 8 direct, but that doesn't work, because the correct
> solution should have been 4,3,2,5,6,8.
>
>
> How do I do this?
>
> Thanks!
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
>

From neilc at norwich.edu  Thu Aug 17 11:11:27 2017
From: neilc at norwich.edu (Neil Cerutti)
Date: Thu, 17 Aug 2017 15:11:27 +0000 (UTC)
Subject: [Tutor] Long post: Request comments on starting code and test
 code on chess rating project.
References: <CANDiX9LshAJbBPctTxKeQsGw3sjWCjtgrDrqy644X+DK90a-Eg@mail.gmail.com>
 <CANDiX9J-LTVczTczV1_kt1MRhH_mWDeK45qyOYfyAKXbjJdh1A@mail.gmail.com>
 <omuva9$tj7$1@blaine.gmane.org> <omvb1r$jiu$1@blaine.gmane.org>
 <CANDiX9Lc-Lt-xQ8-EBwaY+FyxFKbZNaLinMMu1Hji4Rnu4WPCg@mail.gmail.com>
Message-ID: <on4bmv$i2e$1@blaine.gmane.org>

On 2017-08-16, boB Stepp <robertvstepp at gmail.com> wrote:
> On Tue, Aug 15, 2017 at 12:29 PM, Alan Gauld via Tutor
> <tutor at python.org> wrote:
>> On 15/08/17 15:09, Neil Cerutti wrote:
>>>> There are a variety of reports that I would like to be able
>>>> to print to screen or paper.  Things such as a "Top x List"
>>>> of rated players, full rating list sorted from highest
>>>> rating to lowest, rating lists for the current school year
>>>> only or a particular past school year, and so.  ...
>>
>>> You really can do it, but to me this requirement argues for
>>> going back to a database backend. Why rewrite SQL?
>
> I just thought this would be an interesting problem type to
> tackle. No intentions of reinventing SQL!

If you think it'll be fun or interesting, that's a plenty good
reason to do it yourself. On the other hand, practicing the
Python DB-API can be fun and profitable, too. As a near total
neophyte to SQL and databases, attaining the skill of
incoporating sqlite3 into my Python projects took me a couple of
years of on/off again practice. But it has since saved me a ton
of effort.

-- 
Neil Cerutti


From 1019shaun at gmail.com  Thu Aug 17 07:43:27 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Thu, 17 Aug 2017 04:43:27 -0700
Subject: [Tutor] Tutor Digest, Vol 162, Issue 42
In-Reply-To: <mailman.1385.1502957243.2688.tutor@python.org>
References: <mailman.1385.1502957243.2688.tutor@python.org>
Message-ID: <CAG0Jesgxf30f3-Jn3ksnGBzdshV-G6VCQ_t5io8LXoVrRu363w@mail.gmail.com>

On Aug 17, 2017 3:17 AM, <tutor-request at python.org> wrote:

Send Tutor mailing list submissions to
        tutor at python.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://mail.python.org/mailman/listinfo/tutor
or, via email, send a message with subject or body 'help' to
        tutor-request at python.org

You can reach the person managing the list at
        tutor-owner at python.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Tutor digest..."

Today's Topics:

   1. Object takes no parameters (Howard Lawrence)
   2. Re: (no subject) (Zachary Ware)
   3. Re: Object takes no parameters (Alan Gauld)
   4. Re: (no subject) (Alan Gauld)
   5. Re: "Path tree" (Abdur-Rahmaan Janhangeer)
   6. Re: "Path tree" (Michael C)


---------- Forwarded message ----------
From: Howard Lawrence <1019shaun at gmail.com>
To: tutor at python.org
Cc:
Bcc:
Date: Wed, 16 Aug 2017 17:08:47 -0700
Subject: [Tutor] Object takes no parameters
class Human:
     def _init_(self, n, o)
          self.name = n
          self.occupation = o

     def do_work(self):
         if self.occupation== 'tennis player':
            print(self.name, 'plays tennis')

         elif self.occupation == 'actor':
            print(self.name, 'shoots film')

     def speaks(self):
         print(self.name, 'how are you')

tom = Human('tom cruise', 'actor')
tom.do_work()
tom.speak()

Traceback most recent call last
File "c:\users\shaun\python\python35\human_class.py"line 16 in module
tom =Human('tom cruise', 'actor')
TypeError: object() takes no parameters

how to fix this?why it happens?
this happens whenever i try to do
class,this is from a tutorial



---------- Forwarded message ----------
From: Zachary Ware <zachary.ware+pytut at gmail.com>
To: tutor <tutor at python.org>
Cc: Howard Lawrence <1019shaun at gmail.com>
Bcc:
Date: Wed, 16 Aug 2017 20:02:23 -0500
Subject: Re: [Tutor] (no subject)
Hi Howard,

On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com>
wrote:
> class Address:
>         def _init_(self,Hs,St,Town,Zip):

Your issue is in this line, it should be `__init__` rather than
`_init_` (that is, two underscores before and after "init").

Hope this helps,
--
Zach



---------- Forwarded message ----------
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Cc:
Bcc:
Date: Thu, 17 Aug 2017 02:11:43 +0100
Subject: Re: [Tutor] Object takes no parameters
On 17/08/17 01:08, Howard Lawrence wrote:
> class Human:
>      def _init_(self, n, o)
>           self.name = n
>           self.occupation = o
>

>
> tom = Human('tom cruise', 'actor')
>
> Traceback most recent call last
> File "c:\users\shaun\python\python35\human_class.py"line 16 in module
> tom =Human('tom cruise', 'actor')
> TypeError: object() takes no parameters
>
> how to fix this?why it happens?

If you look closely at your tutorial you will find that init()
has two underscores before and after the name:

def __init__()

rather than

def _init_()

The reason for your error is that all classes inherit from object.
So when you call Human() the interpreter looks for an __init__()
method and, not finding one(because yours only has one undercore),
it looks at the one defined in object. But the object init()
takes no parameters and so there is a mismatch between your
call to Human() and the object.__init__() definition.
Hence the error message.

To fix it use two underscores.

All of the "magic" methods used by Python have these double
underscores and  hence are often referred to as "dunder" methods.
You should avoid defining any new methods (ie new names) with
double underscores yourself, in case Python introduces  a
similar method in a future version.

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





---------- Forwarded message ----------
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Cc:
Bcc:
Date: Thu, 17 Aug 2017 02:16:19 +0100
Subject: Re: [Tutor] (no subject)
On 16/08/17 23:36, Howard Lawrence wrote:
> class Address:
>         def _init_(self,Hs,St,Town,Zip):
>                       self.HsNunber=Hs
>                       self.Street=St
>                       self.Town=Town
>                       self.Zip=Zip
> Addr=Address (7, ' high st', 'anytown', ' 123 456')

That looks suspiciously like my tutorial ;-)

The answer is to use two underscores around init():

def __init__(...)

not

def _init_(...)

This is explained in more detail in a box at the end
of the data topic:

http://www.alan-g.me.uk/l2p/tutdata.htm

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


Hey it worked, two underscore did the job, :-) , it's your tutorial! so
look out there is more to come!.. thanks for your help


---------- Forwarded message ----------
From: Abdur-Rahmaan Janhangeer <arj.python at gmail.com>
To: Michael C <mysecretrobotfactory at gmail.com>
Cc: tutor <tutor at python.org>
Bcc:
Date: Thu, 17 Aug 2017 07:22:08 +0400
Subject: Re: [Tutor] "Path tree"
in addition to the answers i'd say now you have the motivation to learn
python data structures and algorithms

http://interactivepython.org/runestone/static/pythonds/index.html

barnum and miller

it is free though i have not found a good pdf book form from where to
download, but you have the site anyway !

Now, the website has more materials than when i first knew it.

hope it helps !

Abdur-Rahmaan Janhangeer,
Mauritius
abdurrahmaanjanhangeer.wordpress.com

On 14 Aug 2017 02:28, "Michael C" <mysecretrobotfactory at gmail.com> wrote:

Hi all:

I am trying to formulate a "path-finding" function, and I am stuck on this
problem:

Please look at the picture attached: Those dots are coordinates of (x,y),
and this tree can be thought of as a list of tuples, with each tuple
consisting of (x,y).  Now I am trying to make a function go through this
list of tuples and then return the "path." to go from, say, 4 to 8. If I
simply compute for the dot for shortest distance, then the solution would
be to go from 4 to 8 direct, but that doesn't work, because the correct
solution should have been 4,3,2,5,6,8.


How do I do this?

Thanks!
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



---------- Forwarded message ----------
From: Michael C <mysecretrobotfactory at gmail.com>
To: Abdur-Rahmaan Janhangeer <arj.python at gmail.com>
Cc: python tutor <tutor at python.org>
Bcc:
Date: Wed, 16 Aug 2017 20:23:35 -0700
Subject: Re: [Tutor] "Path tree"
Ok, I will work with all these. Thx all!

On Aug 16, 2017 20:22, "Abdur-Rahmaan Janhangeer" <arj.python at gmail.com>
wrote:

> in addition to the answers i'd say now you have the motivation to learn
> python data structures and algorithms
>
> http://interactivepython.org/runestone/static/pythonds/index.html
>
> barnum and miller
>
> it is free though i have not found a good pdf book form from where to
> download, but you have the site anyway !
>
> Now, the website has more materials than when i first knew it.
>
> hope it helps !
>
> Abdur-Rahmaan Janhangeer,
> Mauritius
> abdurrahmaanjanhangeer.wordpress.com
>
> On 14 Aug 2017 02:28, "Michael C" <mysecretrobotfactory at gmail.com> wrote:
>
> Hi all:
>
> I am trying to formulate a "path-finding" function, and I am stuck on this
> problem:
>
> Please look at the picture attached: Those dots are coordinates of (x,y),
> and this tree can be thought of as a list of tuples, with each tuple
> consisting of (x,y).  Now I am trying to make a function go through this
> list of tuples and then return the "path." to go from, say, 4 to 8. If I
> simply compute for the dot for shortest distance, then the solution would
> be to go from 4 to 8 direct, but that doesn't work, because the correct
> solution should have been 4,3,2,5,6,8.
>
>
> How do I do this?
>
> Thanks!
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
>


_______________________________________________
Tutor maillist  -  Tutor at python.org
https://mail.python.org/mailman/listinfo/tutor

From 1019shaun at gmail.com  Thu Aug 17 07:45:42 2017
From: 1019shaun at gmail.com (Howard Lawrence)
Date: Thu, 17 Aug 2017 04:45:42 -0700
Subject: [Tutor] (no subject)
In-Reply-To: <CAKJDb-NDDC-9HwnDcjx9_4sFvKNue=_9ourgcjtsDNvTSnfiAg@mail.gmail.com>
References: <CAG0JesjL-a5yW=gJ++5-mcs7xP3-y=m-ZgLqPdVBwrXkQ4thoA@mail.gmail.com>
 <CAG0JesgynYsQSk_Y0tvZRBG44UW2SH2rVvxegwOB3pYs7p3QOA@mail.gmail.com>
 <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
 <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
 <CAKJDb-NDDC-9HwnDcjx9_4sFvKNue=_9ourgcjtsDNvTSnfiAg@mail.gmail.com>
Message-ID: <CAG0Jesh8uECyReWvaOe7UVCUimxZrcEEJo0T7+q1Es_kvwSqfQ@mail.gmail.com>

Yes, it does.

On Aug 16, 2017 8:02 PM, "Zachary Ware" <zachary.ware+pytut at gmail.com>
wrote:

Hi Howard,

On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com>
wrote:
> class Address:
>         def _init_(self,Hs,St,Town,Zip):

Your issue is in this line, it should be `__init__` rather than
`_init_` (that is, two underscores before and after "init").

Hope this helps,
--
Zach


Thanks it worked! Stick around, more to come

From edmundopierre at yahoo.com  Thu Aug 17 09:17:25 2017
From: edmundopierre at yahoo.com (edmundo pierre)
Date: Thu, 17 Aug 2017 13:17:25 +0000 (UTC)
Subject: [Tutor] Help....
References: <848178348.3668288.1502975845208.ref@mail.yahoo.com>
Message-ID: <848178348.3668288.1502975845208@mail.yahoo.com>

I am trying to write a code to solve a system of equation at 2 variables. I used Tkinter to do it. I disigned everything, but I am just stocked when it comes to display the answer on the screen.?
That is the error I am having: ??

Exception in Tkinter callbackTraceback (most recent call last):? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__? ? return self.func(*args)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\ed.py", line 122, in Calculate? ? z = np.linalg.solve ( a, b)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", line 375, in solve? ? r = gufunc(a, b, signature=signature, extobj=extobj)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", line 90, in _raise_linalgerror_singular? ? raise LinAlgError("Singular matrix")numpy.linalg.linalg.LinAlgError: Singular matrix

Hope to get help. Thank you!
Edwin

From mats at wichmann.us  Thu Aug 17 12:39:50 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 17 Aug 2017 10:39:50 -0600
Subject: [Tutor] (no subject)
In-Reply-To: <CAG0Jesh8uECyReWvaOe7UVCUimxZrcEEJo0T7+q1Es_kvwSqfQ@mail.gmail.com>
References: <CAG0JesjL-a5yW=gJ++5-mcs7xP3-y=m-ZgLqPdVBwrXkQ4thoA@mail.gmail.com>
 <CAG0JesgynYsQSk_Y0tvZRBG44UW2SH2rVvxegwOB3pYs7p3QOA@mail.gmail.com>
 <CAG0JesiF2On==tUqZJ2CBzVZL6PQSW43e_jC=tztP5wt6trWAA@mail.gmail.com>
 <CAG0Jesgpr+6ViTjVvAcNO7D8y92na-aG3T+LJGrcFD5wK5mwHw@mail.gmail.com>
 <CAKJDb-NDDC-9HwnDcjx9_4sFvKNue=_9ourgcjtsDNvTSnfiAg@mail.gmail.com>
 <CAG0Jesh8uECyReWvaOe7UVCUimxZrcEEJo0T7+q1Es_kvwSqfQ@mail.gmail.com>
Message-ID: <74ed771b-fae3-da1f-9ca3-1ea620a3c079@wichmann.us>

On 08/17/2017 05:45 AM, Howard Lawrence wrote:
> Yes, it does.
> 
> On Aug 16, 2017 8:02 PM, "Zachary Ware" <zachary.ware+pytut at gmail.com>
> wrote:
> 
> Hi Howard,
> 
> On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com>
> wrote:
>> class Address:
>>         def _init_(self,Hs,St,Town,Zip):
> 
> Your issue is in this line, it should be `__init__` rather than
> `_init_` (that is, two underscores before and after "init").
> 
> Hope this helps,


I would add that typography in a web browser, and sometimes even on the
printed page, may not make the double underscores ('dunder') actually
clearly look like two characters, so until one runs into this lesson The
Hard Way, it might be an easy mistake to make.



From alan.gauld at yahoo.co.uk  Thu Aug 17 12:42:02 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 17 Aug 2017 17:42:02 +0100
Subject: [Tutor] Tutor Digest, Vol 162, Issue 42
In-Reply-To: <CAG0Jesgxf30f3-Jn3ksnGBzdshV-G6VCQ_t5io8LXoVrRu363w@mail.gmail.com>
References: <mailman.1385.1502957243.2688.tutor@python.org>
 <CAG0Jesgxf30f3-Jn3ksnGBzdshV-G6VCQ_t5io8LXoVrRu363w@mail.gmail.com>
Message-ID: <on4h0j$35k$1@blaine.gmane.org>

On 17/08/17 12:43, Howard Lawrence wrote:
> On Aug 17, 2017 3:17 AM, <tutor-request at python.org> wrote:
...
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."

Please follow the instructions. Change the subject line.
And don't post the entire digest, it's hard to find the
new content and everyone has already seen the messages.
And some people pay by the byte so it costs them money.
It is a good way to get people to stop reading your posts...

> Hey it worked, two underscore did the job, :-) , it's your tutorial! so
> look out there is more to come!.. thanks for your help

No problem, but if you read it closely it says that you
need two underscores both in the original section and
in the extra box at the end.

The double underscore issue is probably the most common
issue beginners have with that code so I tried to
emphasise it! Maybe I need to emphasise it in bold :-)

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



From alan.gauld at yahoo.co.uk  Thu Aug 17 12:54:36 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 17 Aug 2017 17:54:36 +0100
Subject: [Tutor] Help....
In-Reply-To: <848178348.3668288.1502975845208@mail.yahoo.com>
References: <848178348.3668288.1502975845208.ref@mail.yahoo.com>
 <848178348.3668288.1502975845208@mail.yahoo.com>
Message-ID: <on4ho4$lqj$1@blaine.gmane.org>

On 17/08/17 14:17, edmundo pierre via Tutor wrote:
> I am trying to write a code to solve a system of equation at 2 variables. 

> I used Tkinter to do it. 

More significantly you used numpy to do it and that seems
to be where the issues lie, not in Tkinter.

Numpy is part of SciPy which has a dedicated support forum

> I disigned everything, but I am just stocked when it> comes to display the answer on the screen.

I'm not sure how you are using Tkinter here because you didn't
send any code but looking at the traceback your code is
getting called by Tkinter somehow.

That aside, the real issue seems to be here:

> File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\ed.py", 
> line 122, in Calculate    
> z = np.linalg.solve ( a, b)  

> File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", 
> line 90, in _raise_linalgerror_singular    
> raise LinAlgError("Singular matrix") numpy.linalg.linalg.LinAlgError: Singular matrix

I have no idea how the numpy stuff works but it looks like a data error,
maybe you are passing the wrong type?

But we'd need to see where 'a' and 'b' come from to be sure.

BTW its probably a bad idea to put your code (ed.py) inside the Python
folder structure, better to have a separate work space for your own
files. Especially if you install another version of Python and
want your code to work with it too.

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



From hgfernan at gmail.com  Fri Aug 18 15:42:17 2017
From: hgfernan at gmail.com (Hilton Fernandes)
Date: Fri, 18 Aug 2017 16:42:17 -0300
Subject: [Tutor] pygame not working
In-Reply-To: <20170817001339.GR7395@ando.pearwood.info>
References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com>
 <20170817001339.GR7395@ando.pearwood.info>
Message-ID: <CAA7w9gnm6SLPh6acDNaWbAnAU3xduCDkX7sFS=AGsg_imShYuQ@mail.gmail.com>

Hello, Quantz Jeremy !

PyGame really has a bad fame with McIntosh computers.

Have you tried the how-to in Pygame official site, at
https://pygame.org/wiki/macintosh

??

Supposing, of course, that you haven't already installed PyGame with
success.

All the best,
Hilton

On Wed, Aug 16, 2017 at 9:13 PM, Steven D'Aprano <steve at pearwood.info>
wrote:

> Hi Quantz Jeremy, or Ethan, which do you prefer?
>
> On Wed, Aug 16, 2017 at 10:33:05AM -0600, Quantz Jeremy wrote:
>
> > I already tried stack overflow, and that didn?t work.
>
> What did you ask, and what answers did they give that didn't work? Or is
> it a secret? :-)
>
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From steve at pearwood.info  Fri Aug 18 22:56:08 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 19 Aug 2017 12:56:08 +1000
Subject: [Tutor] When to use classes
Message-ID: <20170819025607.GT7395@ando.pearwood.info>

Mostly for Bob, but also for anyone else interested:

When To Use Classes

http://kentsjohnson.com/stories/00014.html


He says:

    You may have several functions that use the same state 
    variables, either reading or writing them. You are passing
    a lot of parameters around. You have nested functions that
    have to forward their parameters to the functions they use.
    You are tempted to make some module variables to hold the
    state.

    You could make a class instead!



Indeed you could, and sometimes you should, but we can see a problem 
here. The situation described is a bad situation to be in: there is too 
much coupling between functions, too much state being passed around.

Ideally we should try to *reduce the coupling* between components, if 
possible, and hence make the program less complex. OO design tries to 
encapsulate the coupling within (hopefully) a single class, but it does 
nothing to reduce the coupling or complexity.

So I would say:

- if your code is complex, with lots of connections between 
  components (coupling), try to reduce the coupling and make
  the code simper;

- if you can't, encapsulate it in classes.



-- 
Steve

From robertvstepp at gmail.com  Sat Aug 19 00:26:08 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 18 Aug 2017 23:26:08 -0500
Subject: [Tutor] When to use classes
In-Reply-To: <20170819025607.GT7395@ando.pearwood.info>
References: <20170819025607.GT7395@ando.pearwood.info>
Message-ID: <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>

On Fri, Aug 18, 2017 at 9:56 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Mostly for Bob, but also for anyone else interested:

I guess I'm the "Bob" being referred to.

> When To Use Classes
>
> http://kentsjohnson.com/stories/00014.html
>
>
> He says:
>
>     You may have several functions that use the same state
>     variables, either reading or writing them. You are passing
>     a lot of parameters around. You have nested functions that
>     have to forward their parameters to the functions they use.
>     You are tempted to make some module variables to hold the
>     state.
>
>     You could make a class instead!

>
> Indeed you could, and sometimes you should, but we can see a problem
> here. The situation described is a bad situation to be in: there is too
> much coupling between functions, too much state being passed around.

Excellent point!  This sort of stuff has made it hard for me come up
with good tests.

But I wonder if the author is thinking about something a bit simpler.
In some of my procedural-based programs, I might have started out with
one long, overly complex function.  I think that I need to break this
up into smaller, more single purposed functions, and do so.  But often
this has resulted in a "daisy chain" of functions -- the first
function starts things going, called the next function.  Then that
function calls the next, etc.  When I have found myself in this
situation, there are often a set of values that are needed by several
of these functions, tempting me to "globalize".  But I resist and
instead pass the needed values as arguments.  In this case each
function can be very focused in what it accomplishes, and is easy to
test, but the same values keep being needed by these functions.  I
think this is not necessarily the point you are making?  Anyway, I can
see the author's point that a class would work well here.  A suite of
related methods needs to share the same values and a class would tidy
this up nicely without the need for any globals or needless passing of
the exact same values around as parameters/arguments.

> Ideally we should try to *reduce the coupling* between components, if
> possible, and hence make the program less complex. OO design tries to
> encapsulate the coupling within (hopefully) a single class, but it does
> nothing to reduce the coupling or complexity.
>
> So I would say:
>
> - if your code is complex, with lots of connections between
>   components (coupling), try to reduce the coupling and make
>   the code simper;
>
> - if you can't, encapsulate it in classes.

I really enjoyed reading this brief article.  He explained things
rather clearly.  And he used some modules that I have used (I have yet
to use all of them he cited.).  This got me to examine the csv.py
file, for instance, which proved to be an interesting read in light of
his points.

Thanks for the link, Steve!  This will help me design my current
project better, I'm certain.  At the moment, however, I am studying up
on SQL (Once again.  Maybe I will make it farther this time!) in order
to use sqlite3 in this project.

-- 
boB

From alan.gauld at yahoo.co.uk  Sat Aug 19 03:52:31 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 19 Aug 2017 08:52:31 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>
References: <20170819025607.GT7395@ando.pearwood.info>
 <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>
Message-ID: <on8qnn$ufi$1@blaine.gmane.org>

On 19/08/17 05:26, boB Stepp wrote:

> related methods needs to share the same values and a class would tidy
> this up nicely without the need for any globals or needless passing of
> the exact same values around as parameters/arguments.

Indeed, but its important to remember that class attributes
are in effect just global data confined to a smaller context,
and they share many of the same issues of global data.
Functions(methods) can (and usually do) change the data
as a side effect of being called, without it being obvious
that self.foo() is modifying say, self.bar and self.baz, internally.

The advantage of a class is that at least it constrains the
candidate culprits to other members of our class, but the underlying
problem of changes by side-effect remains, even if reduced.

Classes don't remove the problems with globals, they just
limit the damage.

>> possible, and hence make the program less complex. OO design tries to
>> encapsulate the coupling within (hopefully) a single class, but it does
>> nothing to reduce the coupling or complexity.

exactly so.

> I really enjoyed reading this brief article.  He explained things
> rather clearly.  

Kent was a long time member of this group for many years.
I think he left just about the same time Steve appeared.

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



From alan.gauld at yahoo.co.uk  Sat Aug 19 04:07:43 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 19 Aug 2017 09:07:43 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <on8qnn$ufi$1@blaine.gmane.org>
References: <20170819025607.GT7395@ando.pearwood.info>
 <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>
 <on8qnn$ufi$1@blaine.gmane.org>
Message-ID: <on8rk8$m92$1@blaine.gmane.org>

On 19/08/17 08:52, Alan Gauld via Tutor wrote:

Following up my own post - a sure sign of failure to communicate :-(

> On 19/08/17 05:26, boB Stepp wrote:
> 
>> related methods needs to share the same values and a class would tidy
>> this up nicely without the need for any globals 

> Indeed, but its important to remember that class attributes
> are in effect just global data confined to a smaller context,
> and they share many of the same issues of global data.

> Classes don't remove the problems with globals, they just
> limit the damage.

I should have added that making the globals into instance
variables rather than class attributes improves the
situation still further since it effectively enables
multiple "threads" of execution of your function sequence.

The big issue I was alluding to is the solution whereby a
sequence of functions sharing data is translated into
a Class with class level variables and a bunch of
static/class methods. (This is often seen in bad
Java code). Shared instance data is much less likely
to be changed in bad ways although still a form of global
(within the instance).

But creating classes just to avoid globalizing data
should be a last resort solution. Classes should
serve a conceptual function too in helping to understand
the role of the functions within the overall system.
And that, coincidentally, will usually result in the
functions that share data being grouped in the
same class.

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



From __peter__ at web.de  Sat Aug 19 05:04:33 2017
From: __peter__ at web.de (Peter Otten)
Date: Sat, 19 Aug 2017 11:04:33 +0200
Subject: [Tutor] When to use classes
References: <20170819025607.GT7395@ando.pearwood.info>
Message-ID: <on8uut$ppf$1@blaine.gmane.org>

Steven D'Aprano wrote:

> Mostly for Bob, but also for anyone else interested:
> 
> When To Use Classes
> 
> http://kentsjohnson.com/stories/00014.html

Just a minor nit, but you don't even need a custom function for the callback

result = []
db.query(sql, result.append)

The lesson is that Python already provides some powerful ready-to-use 
classes that take you a long way without having to write your own custom 
classes.

Another alternative to (explicit) classes are generators which are an 
elegant way to hold state and provide a simple interface. 

In modern Python db.query() should be an iterable to that the above can be 
written

result = list(db.query(sql))

(That was easy; but I wonder what tkinter would look like without 
callbacks...)

> He says:
> 
>     You may have several functions that use the same state
>     variables, either reading or writing them. You are passing
>     a lot of parameters around. You have nested functions that
>     have to forward their parameters to the functions they use.
>     You are tempted to make some module variables to hold the
>     state.
> 
>     You could make a class instead!
> 
> 
> 
> Indeed you could, and sometimes you should, but we can see a problem
> here. The situation described is a bad situation to be in: there is too
> much coupling between functions, too much state being passed around.
> 
> Ideally we should try to *reduce the coupling* between components, if
> possible, and hence make the program less complex. OO design tries to
> encapsulate the coupling within (hopefully) a single class, but it does
> nothing to reduce the coupling or complexity.
> 
> So I would say:
> 
> - if your code is complex, with lots of connections between
>   components (coupling), try to reduce the coupling and make
>   the code simper;

Even if you can simplify the code with functions classes often give you a 
nicer interface. Nobody would want to write

a + b * c

as

add(a, mul(b, c))


> - if you can't, encapsulate it in classes.

I think it's important that you say "classes", not "class". As with 
functions three small dedicated classes are much better than one big know-
it-all/do-it-all class.


From robertvstepp at gmail.com  Sat Aug 19 11:52:45 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 19 Aug 2017 10:52:45 -0500
Subject: [Tutor] When to use classes
In-Reply-To: <on8rk8$m92$1@blaine.gmane.org>
References: <20170819025607.GT7395@ando.pearwood.info>
 <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>
 <on8qnn$ufi$1@blaine.gmane.org> <on8rk8$m92$1@blaine.gmane.org>
Message-ID: <CANDiX9JeJL1rk4DWk1wZ99UPViZWHkQjV-5EfOLM1VDOGNmK-g@mail.gmail.com>

On Sat, Aug 19, 2017 at 3:07 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 19/08/17 08:52, Alan Gauld via Tutor wrote:
>
> Following up my own post - a sure sign of failure to communicate :-(
>
>> On 19/08/17 05:26, boB Stepp wrote:
>>
>>> related methods needs to share the same values and a class would tidy
>>> this up nicely without the need for any globals
>
>> Indeed, but its important to remember that class attributes
>> are in effect just global data confined to a smaller context,
>> and they share many of the same issues of global data.

This thought had occurred to me.  Sometimes I wish there was a
mechanism in Python to create a binding to data where both were
unchangeable/immutable.  Yes, I could use an immutable data type, but
if I bind an identifier to it that I want to *only* identify that
data, AFAIK it will always be possible for that identifier to be
rebound to a different object.

>> Classes don't remove the problems with globals, they just
>> limit the damage.
>
> I should have added that making the globals into instance
> variables rather than class attributes improves the
> situation still further since it effectively enables
> multiple "threads" of execution of your function sequence.
>
> The big issue I was alluding to is the solution whereby a
> sequence of functions sharing data is translated into
> a Class with class level variables and a bunch of
> static/class methods. (This is often seen in bad
> Java code). Shared instance data is much less likely
> to be changed in bad ways although still a form of global
> (within the instance).

I think the author was also emphasizing your points, but in a
different way.  He said:

<quote>
Maybe you decided to put your shared state into global variables
instead of creating a class. The single client of your module works
great. But what if you have a second client that needs its own copy of
the module state, or you need to use the module from multiple threads?
You are getting wacky results as the module trips over itself trying
to serve two masters. How can you have two copies of the global state?
Move it into a class! Each client has its own instance of the class
with its own state.
</quote>

> But creating classes just to avoid globalizing data
> should be a last resort solution. Classes should
> serve a conceptual function too in helping to understand
> the role of the functions within the overall system.
> And that, coincidentally, will usually result in the
> functions that share data being grouped in the
> same class.

I did say in my original post "...related methods...", but take the
importance of your point!



-- 
boB

From robertvstepp at gmail.com  Sat Aug 19 12:00:51 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 19 Aug 2017 11:00:51 -0500
Subject: [Tutor] When to use classes
In-Reply-To: <on8uut$ppf$1@blaine.gmane.org>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
Message-ID: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>

On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__peter__ at web.de> wrote:
> Steven D'Aprano wrote:
>
>> Mostly for Bob, but also for anyone else interested:
>>
>> When To Use Classes
>>
>> http://kentsjohnson.com/stories/00014.html
>
> Just a minor nit, but you don't even need a custom function for the callback
>
> result = []
> db.query(sql, result.append)
>
> The lesson is that Python already provides some powerful ready-to-use
> classes that take you a long way without having to write your own custom
> classes.

In my beginning experiments to date writing classes, I have often
while writing my toy examples realized, "Why am I writing a class?
Python already does this more straightforwardly with <insert Python
featured code here>."  Of course not knowing all of Python I sometimes
don't realize this until well after I wrote the unneeded class.

> Another alternative to (explicit) classes are generators which are an
> elegant way to hold state and provide a simple interface.
>
> In modern Python db.query() should be an iterable to that the above can be
> written
>
> result = list(db.query(sql))

I hope I don't forget this point between now and when I get the
database part of my project going!

> (That was easy; but I wonder what tkinter would look like without
> callbacks...)

I wish I knew more so that I could fully wonder about this myself.
You might even be making a clever joke and I am clueless.


>> - if you can't, encapsulate it in classes.
>
> I think it's important that you say "classes", not "class". As with
> functions three small dedicated classes are much better than one big know-
> it-all/do-it-all class.

I try to keep this in mind.  Another thing I'm currently struggling
with is when to use inheritance vs. separate, independent classes.


-- 
boB

From mats at wichmann.us  Sat Aug 19 13:34:10 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 19 Aug 2017 11:34:10 -0600
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
Message-ID: <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us>

On 08/19/2017 10:00 AM, boB Stepp wrote:

>> (That was easy; but I wonder what tkinter would look like without
>> callbacks...)
> 
> I wish I knew more so that I could fully wonder about this myself.
> You might even be making a clever joke and I am clueless.

All graphics frameworks depend heavily on callbacks, to the point where
I'm starting to recognize that callback laden code in other contexts was
probably written by a (former?) graphics programmer :)

It makes some sense though; computational code just goes ahead and
computes.  In the graphical UI world, interesting things happen when an
event you can't exactly plan for takes place.  From the point of view of
a computer program, waiting for somebody to move a mouse and click it is
a slow, infrequent, and unpredictable event, so you set up callbacks
which are invoked when one of those events happens, and in the meantime
you can either do other productive work, or do nothing at all (let other
programs on the computer do work).  I'm finding it hard to imagine
tkinter without them...

>>> - if you can't, encapsulate it in classes.
>>
>> I think it's important that you say "classes", not "class". As with
>> functions three small dedicated classes are much better than one big know-
>> it-all/do-it-all class.
> 
> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

or when to use a class that contains an instance of another class...

It ought to feel natural... there's a lot in common, but we want to do a
little bit of specialization, that's a decent case for inheritance. So
they claim.  Except the examples are always so simplistic in the
literature: write a class called Human, then specialize it into Man and
Woman to deal with gender differences.  Sure.  And as recent political
kerfuffles have highlighted, what about an instance that is not clearly
one or the other?  What about all those pesky little details that are
not as simple as "has two arms" that are never part of the "real world"
models, but are very much part of the programming environment when you
go to implement something?

Inheritance describes a relationship - "is a".  a Volvo is-a Car. A
Checking Account is-a Bank Account. If you can't make that feel natural,
then it's probably not the right model.

(my opinions only)



From unee0x at gmail.com  Sat Aug 19 06:13:48 2017
From: unee0x at gmail.com (kay Cee)
Date: Sat, 19 Aug 2017 06:13:48 -0400
Subject: [Tutor] help with subprocess module
Message-ID: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>

I made a python script that will update a Ubuntu Server every second and
writes asuccess message  and date to a log file, but for some reason the
file is not being written to.

Here is the Script:


#!/usr/bin/python3



import subprocess

import time

import datetime


class UpdateError(Exception):

    pass


def update():

    while True:

        try:

            update_log = open('update_log.txt', 'r+')

            time.sleep(1)

            subprocess.call(['apt-get', 'update', '-y'])

            date = datetime.datetime.now()

            update_log.write("System was updated sucessfully on {}\n".format
(str(date)))

            subprocess.call(['reboot'])


        except UpdateError:

            print("Update Error!!!")


    update_log.close()


if __name__ == '__main__':

    update()

From alan.gauld at yahoo.co.uk  Sat Aug 19 14:23:02 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 19 Aug 2017 19:23:02 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <on8uut$ppf$1@blaine.gmane.org>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
Message-ID: <on9vlu$prd$1@blaine.gmane.org>

On 19/08/17 10:04, Peter Otten wrote:

> nicer interface. Nobody would want to write
> 
> a + b * c
> 
> as
> 
> add(a, mul(b, c))

Unless they program in Lisp perhaps :-)


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



From __peter__ at web.de  Sat Aug 19 14:29:45 2017
From: __peter__ at web.de (Peter Otten)
Date: Sat, 19 Aug 2017 20:29:45 +0200
Subject: [Tutor] help with subprocess module
References: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
Message-ID: <ona02i$d5q$1@blaine.gmane.org>

kay Cee wrote:

> I made a python script that will update a Ubuntu Server every second and
> writes asuccess message  and date to a log file, but for some reason the
> file is not being written to.
> 
> Here is the Script:
> 
> 
> #!/usr/bin/python3
> 
> 
> 
> import subprocess
> 
> import time
> 
> import datetime
> 
> 
> class UpdateError(Exception):
> 
>     pass
> 
> 
> def update():
> 
>     while True:
> 
>         try:
> 
>             update_log = open('update_log.txt', 'r+')
> 
>             time.sleep(1)
> 
>             subprocess.call(['apt-get', 'update', '-y'])
> 
>             date = datetime.datetime.now()
> 
>             update_log.write("System was updated sucessfully on
>             {}\n".format
> (str(date)))
> 
>             subprocess.call(['reboot'])

Hm, are you sure you want to reboot here?

> 
> 
>         except UpdateError:
> 
>             print("Update Error!!!")
> 
> 
>     update_log.close()
> 
> 
> if __name__ == '__main__':
> 
>     update()
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



From alan.gauld at yahoo.co.uk  Sat Aug 19 14:26:56 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 19 Aug 2017 19:26:56 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
Message-ID: <on9vt8$gf2$1@blaine.gmane.org>

On 19/08/17 17:00, boB Stepp wrote:

> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

The golden rule is if the child is not a kind-of the parent then
it should be delegation not inheritance. Never use inheritance as
a mechanism for construction, its for specializing types.

Another anti-pattern to look out for is if you are adding a lot
of new methods rather than overriding inherited methods there's
a good chance you are going the wrong way.

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



From mats at wichmann.us  Sat Aug 19 14:30:37 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 19 Aug 2017 12:30:37 -0600
Subject: [Tutor] help with subprocess module
In-Reply-To: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
References: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
Message-ID: <249bcbc3-0255-c70a-ad3f-f66230032038@wichmann.us>

On 08/19/2017 04:13 AM, kay Cee wrote:
> I made a python script that will update a Ubuntu Server every second and
> writes asuccess message  and date to a log file, but for some reason the
> file is not being written to.
> 
> Here is the Script:
> 
> #!/usr/bin/python3
> 
> import subprocess
> import time
> import datetime
> 
> class UpdateError(Exception):
>     pass
> 
> def update():
>     while True:
>         try:
>             update_log = open('update_log.txt', 'r+')
>             time.sleep(1)
>             subprocess.call(['apt-get', 'update', '-y'])
>             date = datetime.datetime.now()
>             update_log.write("System was updated sucessfully on {}\n".format
> (str(date)))
>             subprocess.call(['reboot'])
>         except UpdateError:
>             print("Update Error!!!")
>     update_log.close()
> 
> if __name__ == '__main__':
>     update()

Hate to not just "answer the question", but what are you trying to
accomplish with this script?

You certainly don't want to call "apt-get update -y" in loop this fast.
Why are you then rebooting? (update doesn't change the system, only the
apt cache info)

Ubuntu has a way to do this stuff as a background task anyway.

For logging, you may want to actually use Python logging facilities.


All those said, the way you want to debug something like this is to run
a much more benign task through subprocess, before moving on to big (and
slow) tasks.


From alan.gauld at yahoo.co.uk  Sat Aug 19 15:29:22 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 19 Aug 2017 20:29:22 +0100
Subject: [Tutor] help with subprocess module
In-Reply-To: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
References: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
Message-ID: <ona3ia$9me$1@blaine.gmane.org>

On 19/08/17 11:13, kay Cee wrote:

> import subprocess
> import time
> import datetime
> 
> class UpdateError(Exception):
>     pass

In defining your own type of Exception you implicitly
say that you will be raising it somewhere. But you
never raise this exception in your code...

> def update():
>     while True:
>         try:
>             update_log = open('update_log.txt', 'r+')
>             time.sleep(1)

Do you really want to run apt-get update every second?
That seems way too frequent, every hour would be a lot,
every day more reasonable.

>             subprocess.call(['apt-get', 'update', '-y'])
>             date = datetime.datetime.now()
>             update_log.write("System was updated sucessfully on {}\n".format
> (str(date)))
>             subprocess.call(['reboot'])

And do you want your computer rebooting after every
successful apt-get update? You really should not have
to do that. Especially every second, you are likely
to make your system unusable.

>         except UpdateError:
>             print("Update Error!!!")

Since nothing raises an UpdateError you will never receive one.
You are more likely to get an OSError or an IOError or a
FileNotFound or similar.

>     update_log.close()

Since you open the file inside the loop you should close
it inside the loop. Ideally inside a finally clause.
Or better still use a with... construct to open the
file then you don;t need to close it yourself.

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



From cs at cskk.id.au  Sat Aug 19 18:43:51 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 20 Aug 2017 08:43:51 +1000
Subject: [Tutor] help with subprocess module
In-Reply-To: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
References: <CAKK_t8vyT8Qv6dJuvFZ+Mh9yeesn5QdWUs8nggFzACprt4J03A@mail.gmail.com>
Message-ID: <20170819224351.GA62867@cskk.homeip.net>

On 19Aug2017 06:13, kay Cee <unee0x at gmail.com> wrote:
>            update_log = open('update_log.txt', 'r+')

Normally one would use 'a' (append) for a log open. I don't see what 'r+' 
accomplishes for you. In particular I expect it would always write at the start 
of the log file, overwriting whatever was there. Which might be your problem.

Others have made other remarks.

I'm not sure any of your problems have to do with the subprocess module itself.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From cs at cskk.id.au  Sat Aug 19 18:39:49 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 20 Aug 2017 08:39:49 +1000
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
References: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
Message-ID: <20170819223949.GA31625@cskk.homeip.net>

On 19Aug2017 11:00, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__peter__ at web.de> wrote:
[...]
>> The lesson is that Python already provides some powerful ready-to-use
>> classes that take you a long way without having to write your own custom
>> classes.
>
>In my beginning experiments to date writing classes, I have often
>while writing my toy examples realized, "Why am I writing a class?
>Python already does this more straightforwardly with <insert Python
>featured code here>."  Of course not knowing all of Python I sometimes
>don't realize this until well after I wrote the unneeded class.

Personally, I do this a lot. It does cost some time, but it also has 
advantages. You get to explore the problem space from the point of view of your 
own needs, and you get insight into the costs/benefits of various ways of doing 
things.

Then you can come back to the presupplied library do various things: understand 
why its interfaces may be designed the way they were, refactor your code (the 
larger problem) on top of the presupplied library, and sometimes decide that 
the presupplied library doesn't meet your needs (or meets them poorly), and 
then you have this useful additional library of your own.

The flipside is to do a little research and start with the presupplied library 
and take that as far as it will go, then build on that. Particularly when the 
library solves some problem you find boring. Also, the presupplied library 
often covers corner cases you may miss - it has (probablym hopefully) been well 
debugged - writing your own has that cost.

You get less insight into internals, but you also get off the ground faster.

>> Another alternative to (explicit) classes are generators which are an
>> elegant way to hold state and provide a simple interface.
[...]
>I hope I don't forget this point between now and when I get the
>database part of my project going!

One thing that I think can be important is to code the upper layers in the 
terms of your larger problem, not in terms of the lower level library's 
interface. In between the two will be functions or methods of your own whose 
interfaces are your own operation, and which call the library to accomplish the 
task, providing some separation between a natural expression of your upper 
level problem and what you might write if you were building from the bottom and 
thinking in the library's terms.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

Ride to not crash. Dress to crash. Live to ride to not crash again.
- Lawrence Smith, DoD#i, lawrence at msc.cornell.edu

From steve at pearwood.info  Sat Aug 19 20:51:42 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 20 Aug 2017 10:51:42 +1000
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9JeJL1rk4DWk1wZ99UPViZWHkQjV-5EfOLM1VDOGNmK-g@mail.gmail.com>
References: <20170819025607.GT7395@ando.pearwood.info>
 <CANDiX9JVawvMmWd7pZAJw-jnVDNG4pORGt8v6U45hKsVOZdvCA@mail.gmail.com>
 <on8qnn$ufi$1@blaine.gmane.org> <on8rk8$m92$1@blaine.gmane.org>
 <CANDiX9JeJL1rk4DWk1wZ99UPViZWHkQjV-5EfOLM1VDOGNmK-g@mail.gmail.com>
Message-ID: <20170820005142.GX7395@ando.pearwood.info>

On Sat, Aug 19, 2017 at 10:52:45AM -0500, boB Stepp wrote:

> This thought had occurred to me.  Sometimes I wish there was a
> mechanism in Python to create a binding to data where both were
> unchangeable/immutable.  Yes, I could use an immutable data type, but
> if I bind an identifier to it that I want to *only* identify that
> data, AFAIK it will always be possible for that identifier to be
> rebound to a different object.

A "constant", in the sense that once bound, it cannot be unbound or 
re-bound to another object.

There are some tricky hacks you can use to get something almost like a 
constant, e.g.

https://code.activestate.com/recipes/65207-constants-in-python/

but without language support they're probably not worth bothering with.


-- 
Steve

From steve at pearwood.info  Sat Aug 19 21:08:35 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 20 Aug 2017 11:08:35 +1000
Subject: [Tutor] When to use classes
In-Reply-To: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
Message-ID: <20170820010834.GY7395@ando.pearwood.info>

On Sat, Aug 19, 2017 at 11:00:51AM -0500, boB Stepp wrote:

> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

Raymond Hettinger has a good video presentation about the use of classes 
and inheritance for delegating work. (That is not to be confused with 
delegation as an alternative to inheritance.)

I think this is the video, but I don't have time to check:

The Art of Subclassing

http://www.youtube.com/watch?v=miGolgp9xq8

If its the one which starts off with him talking about his newly born 
child, it is the one.

And if not, it is probably worth watching anyway, because Raymond's 
talks are always excellent value.

The traditional viewpoint of inheritance is that it is used for 
specialisation, where each subclass is a kind of the parent class:

class Animal:
    # all generic code for animals goes here

class Mammal(Animal):
    # mammals are a kind of animal
    # specialise the animal code for mammals

class Dog(Mammal):
    # dogs are a kind of mammal
    # specialise the mammal code for dogs

class Collie(Dog):
    # collies are a kind of dog
    # specialise the dog code for the collie breed

lassie = Collie()

If you ever hear people talking about the Liskov Substitution Principle, 
that's the model they have in mind. But it's not the only one possible.

Raymond talks about inheritance as expressing a parent-child 
relationship, where the child can delegate tasks to the parent, but the 
child doesn't necessarily need to be seen as "a kind of" whatever the 
parent is.

That's the model used by mixin classes (or traits, a variation on 
mixins).


-- 
Steve

From steve at pearwood.info  Sat Aug 19 21:47:58 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 20 Aug 2017 11:47:58 +1000
Subject: [Tutor] When to use classes
In-Reply-To: <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us>
Message-ID: <20170820014758.GZ7395@ando.pearwood.info>

On Sat, Aug 19, 2017 at 11:34:10AM -0600, Mats Wichmann wrote:

> It makes some sense though; computational code just goes ahead and
> computes.  In the graphical UI world, interesting things happen when an
> event you can't exactly plan for takes place.  From the point of view of
> a computer program, waiting for somebody to move a mouse and click it is
> a slow, infrequent, and unpredictable event, so you set up callbacks
> which are invoked when one of those events happens, and in the meantime
> you can either do other productive work, or do nothing at all (let other
> programs on the computer do work).  I'm finding it hard to imagine
> tkinter without them...

I've never got into GUI programming because I was so thoroughly spoiled 
by one of the first programming languages that I learned that everything 
since then feels like going back to the Dark Ages. Having to care about 
low-level details like creating buttons, installing callbacks and so 
forth just feels wrong.

There is an alternative to callback based GUI frameworks, and that is an 
message-passing, event-driven language. The framework handles the events 
for you, and fires off messages to objects. If the object doesn't handle 
the event, it is sent to the next object in the message-passing 
heirarchy.

The language was Hypertalk, the scripting language of Apple's Hypercard 
application in the mid to late eighties.

Hypercard was seen by Apple as a kind of Rolodex application, with a 
"card" metaphor, and programmable objects (text fields and buttons) that 
you can copy and paste between files. Apple invisiged that developers 
would program the objects and users would simply copy and paste them, 
and to their utter surprise they were overwhelmed by the number of end 
users who started programming their own objects.

By today's standards it is woefully primitive: only a single window, of 
a fixed size, black and white graphics, and only a fixed set of 
pre-defined GUI widgets and no way to create your own. But it is 
remarkable just how much power there is in just two widgets, text fields 
and buttons, especially since the buttons can be specialised into push 
buttons, radio buttons and checkbox buttons.

But I digress... the Hypercard model was that of a stack of cards. Each 
stack (Hypercard document) consisted of at least one shared background 
used by at least one card. Cards inherited their look, state and 
behaviour from their background, but could override any part of that.

You used the integrated GUI designer to lay out your shared objects in 
the background, and customised objects on the card.

The Hypercard application managed the GUI event loop for you. It tracked 
the mouse and the keyboard, and other events, and each time it noticed 
an event, it sent a message to the appropriate object (a widget, card, 
background or stack). That object could either handle the message, or 
ignore it. If it ignored the message, it passed on to the next object in 
the heirachy.

To program your "stack", you create message handlers that respond to 
events. E.g.:

on mouseUp
  # sent when the mouse button is released over the object

on idle
  # sent when nothing else is happening

on opencard
  # sent when we've just navigated to another card

on closecard
  # sent when we've just navigated away from the current card


If this looks a tiny bit like Javascript, that's because Javascript 
borrowed the idea and language of handlers from Hypertalk and 
Hypercard.

To call a handler in another object, you sent your own message, and the 
Hypercard application would manage the details:

send "print" to field "Address" of card "George"

That message would be sent via the same message path as any other event, 
so if the field itself couldn't handle it, it would next go to the card 
"George", then the card's background, then the current stack, and 
finally Hypercard itself, which would complain that it didn't know 
anything about "print" events. (Events it did know about, like idle or 
mouseDown or closeCard, would just be silently ignored.)


-- 
Steve

From alan.gauld at yahoo.co.uk  Sun Aug 20 04:12:27 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 20 Aug 2017 09:12:27 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <20170820014758.GZ7395@ando.pearwood.info>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us>
 <20170820014758.GZ7395@ando.pearwood.info>
Message-ID: <onbg93$egl$1@blaine.gmane.org>

On 20/08/17 02:47, Steven D'Aprano wrote:

> since then feels like going back to the Dark Ages. Having to care about 
> low-level details like creating buttons, installing callbacks and so 
> forth just feels wrong.

To be fair most GUI frameworks come with a GUI builder that remove
the manual coding for things like that. Even Tk (upon which Tkinter
is based) has a couple of them, but for some reason the Python
implementation has never had one that worked well. The bigger
industrial grade GUI builders for Java(Swing/JFX), .NET(VS),
and even Gnome/Qt on Linux are all very easy to use to build
quite complex GUIs.

> There is an alternative to callback based GUI frameworks, and that is an 
> message-passing, event-driven language. The framework handles the events 
> for you, and fires off messages to objects. If the object doesn't handle 
> the event, it is sent to the next object in the message-passing 
> heirarchy.

Again, that's how pretty much every modern GUI works. The
callback bit is just a manual exposure of what the GUI
builder does under the covers. Most casual GUI programmers
never create or specify a call back they just click the widget
in the GUI builder and are taken to the pre-written empty
function body.

> The language was Hypertalk, the scripting language of Apple's Hypercard 
> application in the mid to late eighties.

There was(is?) a project on Sourcefoirge to build a Python
equivalent to Hypercard. I played with it a long time ago
but it wasn't really ready for serious use in my view.
I don't know if its still running or how far it has
progressed.

And there are several GUI builders for Python beyond Tk
although I haven't had much success with any of them.
I suspect because Python is so high level as a language
that the effort they save is much less than when using
Java or C++.

> By today's standards it is woefully primitive: only a single window, of 
> a fixed size, black and white graphics, and only a fixed set of 
> pre-defined GUI widgets and no way to create your own. But it is 
> remarkable just how much power there is in just two widgets, text fields 
> and buttons, especially since the buttons can be specialised into push 
> buttons, radio buttons and checkbox buttons.

Borland tried a similar trick on Windows with a tool called
TurboVision(Or ObjectVision? my memory fails me) which was
an entirely graphical tool with even the code being built using
graphical code blocks. Scratch does the same thing today
for beginning programmers. But all of these tools run
into the same issues - eventually you will need to create
something more complex which the tool can't handle.

> stack (Hypercard document) consisted of at least one shared background 
> used by at least one card. Cards inherited their look, state and 
> behaviour from their background, but could override any part of that.

I think that was Hypercard's USP. The idea of an inherited
look 'n feel was quite powerful and I'm surprised that nobody
else has picked that up, at least as an option, for a new
window/screen/frame.

> The Hypercard application managed the GUI event loop for you. It tracked 
> the mouse and the keyboard, and other events, and each time it noticed 
> an event, it sent a message to the appropriate object (a widget, card, 
> background or stack). That object could either handle the message, or 
> ignore it. If it ignored the message, it passed on to the next object in 
> the heirachy.

Again that's pretty much how every GUI framework operates.
Its just that Tkinter etc make it explicit by forcing you
to pass the parent object and event handler(s) into the
widget at creation time. A GUI builder does that for you.

> If this looks a tiny bit like Javascript, that's because Javascript 
> borrowed the idea and language of handlers from Hypertalk and 
> Hypercard.

Most OO GUI frameworks borrowed these ideas from Hypercard
(and indeed the Object Pascal MacApp framework that
Hypercard was built on). The MaCapp framework was a huge
step up from the older procedural frameworks such as
X Windows and MS Windows etc that had gone before.

> To call a handler in another object, you sent your own message, and the 
> Hypercard application would manage the details:
> 
> send "print" to field "Address" of card "George"
> 
> That message would be sent via the same message path as any other event, 

Again that's pretty much how any GUI framework works
today (although they also allow direct message passing
between code objects too). They all have some kind of
event posting service.

Hypercard's legacy is alive and well in the GUI frameworks
we all use today. The tools used to make that accessible
are not so simple however, and in the end, the ability to
create powerful, full featured GUIs has trumped the easy
to use, but ultimately limited, scope of Hypercard.

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



From jf_byrnes at comcast.net  Sun Aug 20 08:35:08 2017
From: jf_byrnes at comcast.net (Jim)
Date: Sun, 20 Aug 2017 07:35:08 -0500
Subject: [Tutor] When to use classes
In-Reply-To: <onbg93$egl$1@blaine.gmane.org>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us>
 <20170820014758.GZ7395@ando.pearwood.info> <onbg93$egl$1@blaine.gmane.org>
Message-ID: <onbvll$e3h$1@blaine.gmane.org>

On 08/20/2017 03:12 AM, Alan Gauld via Tutor wrote:
> On 20/08/17 02:47, Steven D'Aprano wrote:
> 
>> since then feels like going back to the Dark Ages. Having to care about
>> low-level details like creating buttons, installing callbacks and so
>> forth just feels wrong.
> 
> To be fair most GUI frameworks come with a GUI builder that remove
> the manual coding for things like that. Even Tk (upon which Tkinter
> is based) has a couple of them, but for some reason the Python
> implementation has never had one that worked well. The bigger
> industrial grade GUI builders for Java(Swing/JFX), .NET(VS),
> and even Gnome/Qt on Linux are all very easy to use to build
> quite complex GUIs.
> 
>> There is an alternative to callback based GUI frameworks, and that is an
>> message-passing, event-driven language. The framework handles the events
>> for you, and fires off messages to objects. If the object doesn't handle
>> the event, it is sent to the next object in the message-passing
>> heirarchy.
> 
> Again, that's how pretty much every modern GUI works. The
> callback bit is just a manual exposure of what the GUI
> builder does under the covers. Most casual GUI programmers
> never create or specify a call back they just click the widget
> in the GUI builder and are taken to the pre-written empty
> function body.
> 
>> The language was Hypertalk, the scripting language of Apple's Hypercard
>> application in the mid to late eighties.
> 
> There was(is?) a project on Sourcefoirge to build a Python
> equivalent to Hypercard. I played with it a long time ago
> but it wasn't really ready for serious use in my view.
> I don't know if its still running or how far it has
> progressed.
> 
> And there are several GUI builders for Python beyond Tk
> although I haven't had much success with any of them.
> I suspect because Python is so high level as a language
> that the effort they save is much less than when using
> Java or C++.
> 
>> By today's standards it is woefully primitive: only a single window, of
>> a fixed size, black and white graphics, and only a fixed set of
>> pre-defined GUI widgets and no way to create your own. But it is
>> remarkable just how much power there is in just two widgets, text fields
>> and buttons, especially since the buttons can be specialised into push
>> buttons, radio buttons and checkbox buttons.
> 
> Borland tried a similar trick on Windows with a tool called
> TurboVision(Or ObjectVision? my memory fails me) which was
> an entirely graphical tool with even the code being built using
> graphical code blocks. Scratch does the same thing today
> for beginning programmers. But all of these tools run
> into the same issues - eventually you will need to create
> something more complex which the tool can't handle.
> 
>> stack (Hypercard document) consisted of at least one shared background
>> used by at least one card. Cards inherited their look, state and
>> behaviour from their background, but could override any part of that.
> 
> I think that was Hypercard's USP. The idea of an inherited
> look 'n feel was quite powerful and I'm surprised that nobody
> else has picked that up, at least as an option, for a new
> window/screen/frame.
> 
>> The Hypercard application managed the GUI event loop for you. It tracked
>> the mouse and the keyboard, and other events, and each time it noticed
>> an event, it sent a message to the appropriate object (a widget, card,
>> background or stack). That object could either handle the message, or
>> ignore it. If it ignored the message, it passed on to the next object in
>> the heirachy.
> 
> Again that's pretty much how every GUI framework operates.
> Its just that Tkinter etc make it explicit by forcing you
> to pass the parent object and event handler(s) into the
> widget at creation time. A GUI builder does that for you.
> 
>> If this looks a tiny bit like Javascript, that's because Javascript
>> borrowed the idea and language of handlers from Hypertalk and
>> Hypercard.
> 
> Most OO GUI frameworks borrowed these ideas from Hypercard
> (and indeed the Object Pascal MacApp framework that
> Hypercard was built on). The MaCapp framework was a huge
> step up from the older procedural frameworks such as
> X Windows and MS Windows etc that had gone before.
> 
>> To call a handler in another object, you sent your own message, and the
>> Hypercard application would manage the details:
>>
>> send "print" to field "Address" of card "George"
>>
>> That message would be sent via the same message path as any other event,
> 
> Again that's pretty much how any GUI framework works
> today (although they also allow direct message passing
> between code objects too). They all have some kind of
> event posting service.
> 
> Hypercard's legacy is alive and well in the GUI frameworks
> we all use today. The tools used to make that accessible
> are not so simple however, and in the end, the ability to
> create powerful, full featured GUIs has trumped the easy
> to use, but ultimately limited, scope of Hypercard.
> 

In one sense Hypercard is still alive. Check out Livecode at livecode.com

Regards,  Jim




From robertvstepp at gmail.com  Sun Aug 20 22:06:51 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 20 Aug 2017 21:06:51 -0500
Subject: [Tutor] When to use classes
In-Reply-To: <20170820010834.GY7395@ando.pearwood.info>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <20170820010834.GY7395@ando.pearwood.info>
Message-ID: <CANDiX9K4r2tSBFcuOsnEOzHUEmxxdo_AKZ4yzooOUL-agDaFrg@mail.gmail.com>

On Sat, Aug 19, 2017 at 8:08 PM, Steven D'Aprano <steve at pearwood.info> wrote:

> The Art of Subclassing
>
> http://www.youtube.com/watch?v=miGolgp9xq8
>
> If its the one which starts off with him talking about his newly born
> child, it is the one.

This is indeed the "one"!

> The traditional viewpoint of inheritance is that it is used for
> specialisation, where each subclass is a kind of the parent class:
>
> class Animal:
>     # all generic code for animals goes here
>
> class Mammal(Animal):
>     # mammals are a kind of animal
>     # specialise the animal code for mammals
>
> class Dog(Mammal):
>     # dogs are a kind of mammal
>     # specialise the mammal code for dogs
>
> class Collie(Dog):
>     # collies are a kind of dog
>     # specialise the dog code for the collie breed
>
> lassie = Collie()
>
> If you ever hear people talking about the Liskov Substitution Principle,
> that's the model they have in mind. But it's not the only one possible.
>
> Raymond talks about inheritance as expressing a parent-child
> relationship, where the child can delegate tasks to the parent, but the
> child doesn't necessarily need to be seen as "a kind of" whatever the
> parent is.
>
> That's the model used by mixin classes (or traits, a variation on
> mixins).

Well the video has put a new twist on things:  Choose the parent class
to be the one which maximizes code reuse instead of thinking in terms
of classic specialization.  And the children are in charge, not the
parents!  Interesting stuff!

-- 
boB

From alan.gauld at yahoo.co.uk  Tue Aug 22 06:51:35 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 22 Aug 2017 11:51:35 +0100
Subject: [Tutor] When to use classes
In-Reply-To: <20170820010834.GY7395@ando.pearwood.info>
References: <20170819025607.GT7395@ando.pearwood.info>
 <on8uut$ppf$1@blaine.gmane.org>
 <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <20170820010834.GY7395@ando.pearwood.info>
Message-ID: <onh2bf$69l$1@blaine.gmane.org>

On 20/08/17 02:08, Steven D'Aprano wrote:

> Raymond Hettinger has a good video presentation about the use of classes 
> and inheritance for delegating work. (That is not to be confused with 
> delegation as an alternative to inheritance.)

No, but I think it would have been useful if he had made that
distinction explicit. Many people hear delegation and think
one thing, and especially when he also threw in the word
re-use which is often the excuse for misuse of inheritance.

> The Art of Subclassing
> 
> http://www.youtube.com/watch?v=miGolgp9xq8

> Raymond talks about inheritance as expressing a parent-child 
> relationship, where the child can delegate tasks to the parent, but the 
> child doesn't necessarily need to be seen as "a kind of" whatever the 
> parent is.

While I actually agree with much of what Raymond says I think
he fell into the trap that is very common in conference talks
 - an expert talking to other experts missing out some important
assumed knowledge.

In particular he talks about choosing the subclass pattern
that maximises reuse of code. What he did not say, however,
was that you should use inheritance as a means of reusing
code - that's a very different thing and usually has
bad results. But a naive viewer could come away from his
talk with the idea that he was advocating that, and I
don't believe he was. It is true that the amount of
code-reuse is a strong indicator of which way round
a parent-child relationship would go but we shouldn't
inherit a class just to reuse some method within it.

Unfortunately he used the old Circle-Ellipse case (he could
equally have used the square-rectangle conundrum) and
implied that there were two solutions, neither ideal.
What he omitted is the third solution, that most OOP gurus
now recommend, that circles and ellipses are not the
same and should therefore both inherit as peers from
Shape. That implies less code reuse but avoids the
problem of trying to force circles to behave as ellipses
or vice-versa.

He did emphasise the importance of substitution and of
using the LSP (and specifically deviations from it)
as a tool for identifying where the class(and sub-class)
designer has to do extra work to support future sub-classing.

> That's the model used by mixin classes (or traits, a variation on 
> mixins).

That's true, although the big difference is that mixins
are an implementation level of inheritance rather
than conceptual. (ie a class that uses mixins will nearly
always have a "true" kind-of inheritance in its superclasses
too) Also classes intended for use as mixins usually provide
a capability rather than representing a real-world object.
(eg persistence, serializability, logging, security etc)
They are a code reuse mechanism rather than part of the
conceptual framework of the object model. Mixins are a
great way to turn a purely abstract conceptual model into
a concrete implementation fit for the real world without
breaking the integrity of the original concept.

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



From neilc at norwich.edu  Tue Aug 22 10:44:33 2017
From: neilc at norwich.edu (Neil Cerutti)
Date: Tue, 22 Aug 2017 14:44:33 +0000 (UTC)
Subject: [Tutor] When to use classes
References: <CANDiX9KK5PcBFEX+yC1ZVtyiiYFt=rBJ664k+3H=v186RHYJJw@mail.gmail.com>
 <20170819223949.GA31625@cskk.homeip.net>
Message-ID: <onhg0h$h4h$1@blaine.gmane.org>

On 2017-08-19, Cameron Simpson <cs at cskk.id.au> wrote:
> Personally, I do this a lot. It does cost some time, but it
> also has advantages. You get to explore the problem space from
> the point of view of your own needs, and you get insight into
> the costs/benefits of various ways of doing things.

Sometimes I use classes simply because it provides a convenient
way to organize the project's functions.

This crops up sometimes when I'm translating some data into
another form. Every object translates into itself.

-- 
Neil Cerutti


From tmrsg11 at gmail.com  Thu Aug 24 09:51:49 2017
From: tmrsg11 at gmail.com (C W)
Date: Thu, 24 Aug 2017 09:51:49 -0400
Subject: [Tutor] Does matplotlib.finance still work?
Message-ID: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>

Hello all,

I have the following code, I get an error at the first line.

from matplotlib.finance import quotes_historical_yahoo_ochl
from datetime import date
import pandas as pd
today = date.today()
start = date(today.year-1, today.month, today.day)
quotes = quotes_historical_yahoo_ochl('APX', start, today)


I have heard this package is either upgraded or replaced. If so, what do
you recommend?

Thanks!

From alan.gauld at yahoo.co.uk  Thu Aug 24 12:46:57 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 24 Aug 2017 17:46:57 +0100
Subject: [Tutor] Does matplotlib.finance still work?
In-Reply-To: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
References: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
Message-ID: <onmvto$9qu$1@blaine.gmane.org>

On 24/08/17 14:51, C W wrote:

> I have the following code, I get an error at the first line.

So don't make us guess. What is the error(full text please)?

> from matplotlib.finance import quotes_historical_yahoo_ochl

And what does a dir() show for matplotlib.finance?
Are you sure the name is spelled right etc?

> I have heard this package is either upgraded or replaced. If so, what do
> you recommend?

Contact its author perhaps?

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



From s.shall at virginmedia.com  Fri Aug 25 06:01:29 2017
From: s.shall at virginmedia.com (Sydney Shall)
Date: Fri, 25 Aug 2017 12:01:29 +0200
Subject: [Tutor] Does matplotlib.finance still work?
In-Reply-To: <onmvto$9qu$1@blaine.gmane.org>
References: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
 <onmvto$9qu$1@blaine.gmane.org>
Message-ID: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com>

On 24/08/2017 18:46, Alan Gauld via Tutor wrote:
> On 24/08/17 14:51, C W wrote:
> 
>> I have the following code, I get an error at the first line.
> 
> So don't make us guess. What is the error(full text please)?
> 
>> from matplotlib.finance import quotes_historical_yahoo_ochl
> 
> And what does a dir() show for matplotlib.finance?
> Are you sure the name is spelled right etc?
> 
>> I have heard this package is either upgraded or replaced. If so, what do
>> you recommend?
> 
> Contact its author perhaps?
> 


Is this the answer, perhaps.

 >>>import matplotlib

 >>>dir(matplotlib.finance)
 >>>Traceback (most recent call last):

   File "<ipython-input-2-87d00fcbe86c>", line 1, in <module>
     dir(matplotlib.finance)

   AttributeError: module 'matplotlib' has no attribute 'finance'

Thanks to Alan G? for his excellent teaching.

-- 
Sydney

From tmrsg11 at gmail.com  Fri Aug 25 10:19:45 2017
From: tmrsg11 at gmail.com (C W)
Date: Fri, 25 Aug 2017 10:19:45 -0400
Subject: [Tutor] Does matplotlib.finance still work?
In-Reply-To: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com>
References: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
 <onmvto$9qu$1@blaine.gmane.org>
 <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com>
Message-ID: <CAE2FW2=MWiYeZ_e5sBkADRw+KTWdOA8qMUEHkY+B=NcndzqB+w@mail.gmail.com>

I did not mean to leave out the error message, it was very long. I think
the package has been removed.

Anyways, it's here:

>>> quotes = quotes_historical_yahoo_ochl('APX', start, ... )
------------------------------
TypeError: quotes_historical_yahoo_ochl() missing 1 required positional
argument: 'date2'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-725-467118fe2a8b> in <module>() ----> 1 quotes =
quotes_historical_yahoo_ochl('APX', start, 2 )
TypeError: quotes_historical_yahoo_ochl() missing 1 required positional
argument: 'date2'
------------------------------
------------------------------
>>>
------------------------------
>>> quotes = quotes_historical_yahoo_ochl('APX', start, today)
------------------------------
URLError: <urlopen error [Errno 8] nodename nor servname provided, or not
known>
---------------------------------------------------------------------------
gaierror Traceback (most recent call last)
/Users/anaconda/lib/python3.6/urllib/request.py in do_open(self,
http_class, req, **http_conn_args) 1317 h.request(req.get_method(),
req.selector, req.data, headers, -> 1318
encode_chunked=req.has_header('Transfer-encoding')) 1319 except OSError as
err: # timeout error
/Users/anaconda/lib/python3.6/http/client.py in request(self, method, url,
body, headers, encode_chunked) 1238 """Send a complete request to the
server.""" -> 1239 self._send_request(method, url, body, headers,
encode_chunked) 1240
/Users/anaconda/lib/python3.6/http/client.py in _send_request(self, method,
url, body, headers, encode_chunked) 1284 body = _encode(body, 'body') ->
1285 self.endheaders(body, encode_chunked=encode_chunked) 1286
/Users/anaconda/lib/python3.6/http/client.py in endheaders(self,
message_body, encode_chunked) 1233 raise CannotSendHeader() -> 1234 self.
_send_output(message_body, encode_chunked=encode_chunked) 1235
/Users/anaconda/lib/python3.6/http/client.py in _send_output(self,
message_body, encode_chunked) 1025 del self._buffer[:] -> 1026 self.send(msg
) 1027
/Users/anaconda/lib/python3.6/http/client.py in send(self, data) 963 if self
.auto_open: --> 964 self.connect() 965 else:
/Users/anaconda/lib/python3.6/http/client.py in connect(self) 935 self.sock
= self._create_connection( --> 936 (self.host,self.port), self.timeout,
self.source_address) 937 self.sock.setsockopt(socket.IPPROTO_TCP, socket.
TCP_NODELAY, 1)
/Users/anaconda/lib/python3.6/socket.py in create_connection(address,
timeout, source_address) 703 err = None --> 704 for res in getaddrinfo(host,
port, 0, SOCK_STREAM): 705 af, socktype, proto, canonname, sa = res
/Users/anaconda/lib/python3.6/socket.py in getaddrinfo(host, port, family,
type, proto, flags) 742 addrlist = [] --> 743 for res in _socket.getaddrinfo
(host, port, family, type, proto, flags): 744 af, socktype, proto, canonname
, sa = res
gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
URLError Traceback (most recent call last)
<ipython-input-727-df8864d6e732> in <module>() ----> 1 quotes =
quotes_historical_yahoo_ochl('APX', start, today)
/Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted,
cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2,
asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413
ochl=True) 414 415
/Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
_quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted,
cachename, ochl) 501 # warnings.warn("Recommend changing to asobject=None")
502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename) 504
505 try:
/Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
fetch_historical_yahoo(ticker, date1, date2, cachename, dividends) 360 else:
361 mkdirs(os.path.abspath(os.path.dirname(cachename))) --> 362 with
contextlib.closing(urlopen(url)) as urlfh: 363 with open(cachename, 'wb') as
fh: 364 fh.write(urlfh.read())
/Users/anaconda/lib/python3.6/urllib/request.py in urlopen(url, data,
timeout, cafile, capath, cadefault, context) 221 else: 222 opener = _opener -->
223 return opener.open(url, data, timeout) 224 225 def install_opener(opener
):
/Users/anaconda/lib/python3.6/urllib/request.py in open(self, fullurl,
data, timeout) 524 req = meth(req) 525 --> 526 response = self._open(req,
data) 527 528 # post-process response
/Users/anaconda/lib/python3.6/urllib/request.py in _open(self, req, data)
542 protocol = req.type 543 result = self._call_chain(self.handle_open,
protocol, protocol + --> 544 '_open', req) 545 if result: 546 return result
/Users/anaconda/lib/python3.6/urllib/request.py in _call_chain(self, chain,
kind, meth_name, *args) 502 for handler in handlers: 503 func = getattr(
handler, meth_name) --> 504 result = func(*args) 505 if result is not None:
506 return result
/Users/anaconda/lib/python3.6/urllib/request.py in http_open(self, req) 1344
1345 def http_open(self, req): -> 1346 return self.do_open(http.client.
HTTPConnection, req) 1347 1348 http_request = AbstractHTTPHandler.
do_request_
/Users/anaconda/lib/python3.6/urllib/request.py in do_open(self,
http_class, req, **http_conn_args) 1318
encode_chunked=req.has_header('Transfer-encoding')) 1319 except OSError as
err: # timeout error -> 1320 raise URLError(err) 1321 r = h.getresponse()
1322 except:
URLError: <urlopen error [Errno 8] nodename nor servname provided, or not
known>

On Fri, Aug 25, 2017 at 6:01 AM, Sydney Shall <s.shall at virginmedia.com>
wrote:

> On 24/08/2017 18:46, Alan Gauld via Tutor wrote:
>
>> On 24/08/17 14:51, C W wrote:
>>
>> I have the following code, I get an error at the first line.
>>>
>>
>> So don't make us guess. What is the error(full text please)?
>>
>> from matplotlib.finance import quotes_historical_yahoo_ochl
>>>
>>
>> And what does a dir() show for matplotlib.finance?
>> Are you sure the name is spelled right etc?
>>
>> I have heard this package is either upgraded or replaced. If so, what do
>>> you recommend?
>>>
>>
>> Contact its author perhaps?
>>
>>
>
> Is this the answer, perhaps.
>
> >>>import matplotlib
>
> >>>dir(matplotlib.finance)
> >>>Traceback (most recent call last):
>
>   File "<ipython-input-2-87d00fcbe86c>", line 1, in <module>
>     dir(matplotlib.finance)
>
>   AttributeError: module 'matplotlib' has no attribute 'finance'
>
> Thanks to Alan G? for his excellent teaching.
>
> --
> Sydney
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From alan.gauld at yahoo.co.uk  Fri Aug 25 13:01:33 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 25 Aug 2017 18:01:33 +0100
Subject: [Tutor] Does matplotlib.finance still work?
In-Reply-To: <CAE2FW2=MWiYeZ_e5sBkADRw+KTWdOA8qMUEHkY+B=NcndzqB+w@mail.gmail.com>
References: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
 <onmvto$9qu$1@blaine.gmane.org>
 <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com>
 <CAE2FW2=MWiYeZ_e5sBkADRw+KTWdOA8qMUEHkY+B=NcndzqB+w@mail.gmail.com>
Message-ID: <onpl55$a8m$1@blaine.gmane.org>

On 25/08/17 15:19, C W wrote:
> I did not mean to leave out the error message, it was very long.

That just means it has a lot of information in it :-)

>  I think the package has been removed.

I don;t think so based on the traceback...

>>>> quotes = quotes_historical_yahoo_ochl('APX', start, ... )
> ------------------------------
> TypeError: quotes_historical_yahoo_ochl() missing 1 required positional
> argument: 'date2'

Did you check what parameters were required for this function?
The error says you are missing one.

> /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in

Note the filename. That suggests finance.py is still there.

> quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted,
> cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2,
> asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413
> ochl=True) 414 415
> /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
> _quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted,
> cachename, ochl) 501 # warnings.warn("Recommend changing to asobject=None")
> 502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename) 504
> 505 try:

Some warnings there that might be relevant, I don't know
anything about the package or function.

You could try running the help() function:

>>> help(quotes_historical_yahoo_ochl)

And see if it shows anything useful.

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



From robertvstepp at gmail.com  Fri Aug 25 20:13:12 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 25 Aug 2017 19:13:12 -0500
Subject: [Tutor] How to use subprocess module to get current logged in user?
Message-ID: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>

SunOS 5.10, Python 2.4/2.6

I ask forgiveness in advance as I cannot copy and paste into an email
what I am doing on this system.  So I will have to manually type
things, introducing the usual possibility of typos.

My objective:  Determine who the currently logged in user is and
determine if that user is in my list of users that I have authorized
to use my programs.

I tried in the interpreter:

=================================================================================================
py2> cmd = ['who', '-m']
py2> import subprocess as sp
py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
py2> out, err = p.communicate()
py2> out
''
py2> err
"Must be attached to terminal for 'am I' option\n"
py2> p = sp.Popen(cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE,
stderr=sp.PIPE)
py2> out, err = p.communicate()
py2> out
'rstepp ...' followed by all the other currently logged in users as if
I had just typed 'who' in the terminal.
=================================================================================================

What am I doing wrong?  Why cannot I get the '-m' to be used?  And is
there an easier way to accomplish my objective?

If I cannot work this out, then I will be forced to do:

py2> import os
py2> current_usr = os.popen('who -m')

This should not be a security issue for me as no user input is
involved.  But I would rather use the subprocess module.

TIA!

-- 
boB

From steve at pearwood.info  Fri Aug 25 21:33:38 2017
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 26 Aug 2017 11:33:38 +1000
Subject: [Tutor] How to use subprocess module to get current logged in
 user?
In-Reply-To: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
References: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
Message-ID: <20170826013338.GB9671@ando.pearwood.info>

On Fri, Aug 25, 2017 at 07:13:12PM -0500, boB Stepp wrote:

> My objective:  Determine who the currently logged in user is

py> import os
py> os.getlogin()
'steve'


> and
> determine if that user is in my list of users that I have authorized
> to use my programs.

That's probably best handled at the OS level, by setting your programs 
to be executable only by members of a particular group. In Linux, the 
relevant commands are chmod and chgrp but I don't know what they are in 
Solaris.


> I tried in the interpreter:
> 
> =================================================================================================
> py2> cmd = ['who', '-m']
> py2> import subprocess as sp
> py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
> py2> out, err = p.communicate()
> py2> out
> ''
> py2> err
> "Must be attached to terminal for 'am I' option\n"

Check the documentation for who on your system, e.g. man who, but my 
guess is that the -m or "am I" option requires you to be attached to a 
terminal. By launching a subprocess, you're no longer attached to one.

Under my Linux system, the above gives no output or error.

No, I don't understand it either :-)

But reading man who tells me that the -m option returns the user 
connected to stdin. Sure enough, this works:

py> p = sp.Popen(cmd, stdin=sys.stdin, stdout=sp.PIPE, stderr=sp.PIPE)
py> out, err = p.communicate()
py> out
'steve    pts/5        2017-08-25 15:52 (:0.0)\n'



-- 
Steve

From mats at wichmann.us  Fri Aug 25 21:39:17 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 25 Aug 2017 19:39:17 -0600
Subject: [Tutor] How to use subprocess module to get current logged in
 user?
In-Reply-To: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
References: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
Message-ID: <9427FCFA-03A7-4BD8-835F-65B3575A41C2@wichmann.us>

import getpass 
getpass.getuser ()

depending on how fussy you want to be...

On August 25, 2017 6:13:12 PM MDT, boB Stepp <robertvstepp at gmail.com> wrote:
>SunOS 5.10, Python 2.4/2.6
>
>I ask forgiveness in advance as I cannot copy and paste into an email
>what I am doing on this system.  So I will have to manually type
>things, introducing the usual possibility of typos.
>
>My objective:  Determine who the currently logged in user is and
>determine if that user is in my list of users that I have authorized
>to use my programs.
>
>I tried in the interpreter:
>
>=================================================================================================
>py2> cmd = ['who', '-m']
>py2> import subprocess as sp
>py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
>py2> out, err = p.communicate()
>py2> out
>''
>py2> err
>"Must be attached to terminal for 'am I' option\n"
>py2> p = sp.Popen(cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE,
>stderr=sp.PIPE)
>py2> out, err = p.communicate()
>py2> out
>'rstepp ...' followed by all the other currently logged in users as if
>I had just typed 'who' in the terminal.
>=================================================================================================
>
>What am I doing wrong?  Why cannot I get the '-m' to be used?  And is
>there an easier way to accomplish my objective?
>
>If I cannot work this out, then I will be forced to do:
>
>py2> import os
>py2> current_usr = os.popen('who -m')
>
>This should not be a security issue for me as no user input is
>involved.  But I would rather use the subprocess module.
>
>TIA!
>
>-- 
>boB
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

From robertvstepp at gmail.com  Fri Aug 25 22:42:09 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 25 Aug 2017 21:42:09 -0500
Subject: [Tutor] How to use subprocess module to get current logged in
 user?
In-Reply-To: <20170826013338.GB9671@ando.pearwood.info>
References: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
 <20170826013338.GB9671@ando.pearwood.info>
Message-ID: <CANDiX9+mOFxUJ1PJkZxjqNmX3nTiqpauoXbwhtuYMLinOhw6kA@mail.gmail.com>

On Fri, Aug 25, 2017 at 8:33 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Aug 25, 2017 at 07:13:12PM -0500, boB Stepp wrote:
>
>> My objective:  Determine who the currently logged in user is
>
> py> import os
> py> os.getlogin()
> 'steve'

Sweet!  Much better.  I did not scan the os modules closely enough.

>
>> and
>> determine if that user is in my list of users that I have authorized
>> to use my programs.
>
> That's probably best handled at the OS level, by setting your programs
> to be executable only by members of a particular group. In Linux, the
> relevant commands are chmod and chgrp but I don't know what they are in
> Solaris.

If that was all I needed the user name for (Sorry!  I did not mention
*everything*.), then I would probably go this route.  I also will have
certain default configuration information associated with each user.
But it sounds like it is probably better to do what you suggest, and
then do the configuration settings as planned.

>
>> I tried in the interpreter:
>>
>> =================================================================================================
>> py2> cmd = ['who', '-m']
>> py2> import subprocess as sp
>> py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
>> py2> out, err = p.communicate()
>> py2> out
>> ''
>> py2> err
>> "Must be attached to terminal for 'am I' option\n"
>
> Check the documentation for who on your system, e.g. man who, but my
> guess is that the -m or "am I" option requires you to be attached to a
> terminal. By launching a subprocess, you're no longer attached to one.

I had checked the man pages for who, but did not appreciate/realize
that my launched subprocess was not attached to the user's terminal.
I probably should have realized this though, in retrospect.

> Under my Linux system, the above gives no output or error.
>
> No, I don't understand it either :-)
>
> But reading man who tells me that the -m option returns the user
> connected to stdin. Sure enough, this works:
>
> py> p = sp.Popen(cmd, stdin=sys.stdin, stdout=sp.PIPE, stderr=sp.PIPE)
> py> out, err = p.communicate()
> py> out
> 'steve    pts/5        2017-08-25 15:52 (:0.0)\n'

Works for me, too.  Thanks, Steve!

-- 
boB

From alan.gauld at yahoo.co.uk  Sat Aug 26 03:21:12 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 26 Aug 2017 08:21:12 +0100
Subject: [Tutor] How to use subprocess module to get current logged in
 user?
In-Reply-To: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
References: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
Message-ID: <onr7gv$7cj$1@blaine.gmane.org>


> My objective:  Determine who the currently logged in user is and
> determine if that user is in my list of users that I have authorized
> to use my programs.

In addition to Steve and Mats answers:

import os
os.getlogin()   #-> 'alan'
os.getuid() #-> 1001

import pwd
pwd.getpwuid(os.getuid()) #-> loads of user related stuff...

You can also use the environment variables such as

os.getenv('USER') #-> 'alan'
os.getenv('HOME') #-> '/home/alan'

the latter being a useful place to look for the
individual config file... You can use os.environ
if you prefer a dictionary style to a function.

And of course

os.cwd() #-> '/home/alan'

For the current directory.

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



From tmrsg11 at gmail.com  Sat Aug 26 13:16:55 2017
From: tmrsg11 at gmail.com (C W)
Date: Sat, 26 Aug 2017 13:16:55 -0400
Subject: [Tutor] Does matplotlib.finance still work?
In-Reply-To: <onpl55$a8m$1@blaine.gmane.org>
References: <CAE2FW2kj_h7yyQ7FpALCYtKSvJAbTh_2OECp88PLXdEEa7-TWg@mail.gmail.com>
 <onmvto$9qu$1@blaine.gmane.org>
 <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com>
 <CAE2FW2=MWiYeZ_e5sBkADRw+KTWdOA8qMUEHkY+B=NcndzqB+w@mail.gmail.com>
 <onpl55$a8m$1@blaine.gmane.org>
Message-ID: <CAE2FW2m0Fng2ODcPccMO7y2zZRVuMiRFc6ugW+d8JD_ZW3VVDw@mail.gmail.com>

Thanks Alan. You are right, the finance.py is there.

I think quotes_historical_yahoo is from 3 years ago. It is replaced by
quotes_historical_yahoo_ochl and quotes_historical_yahoo_ohlc.

But the problem is, yahoo finance has also changed its API (2 years ago?).
It is a complete overhaul.

quotes_historical_yahoo_ochl has not kept up. Thus, the error message.

help(quotes_historical_yahoo_ochl)
------------------------------
Help on function quotes_historical_yahoo_ochl in module matplotlib.finance:
quotes_historical_yahoo_ochl(ticker, date1, date2, asobject=False,
adjusted=True, cachename=None) Get historical data for ticker between date1
and date2. See :func:`parse_yahoo_historical` for explanation of output
formats and the *asobject* and *adjusted* kwargs. Parameters ----------
ticker : str stock ticker date1 : sequence of form (year, month, day),
`datetime`, or `date` start date date2 : sequence of form (year, month,
day), `datetime`, or `date` end date cachename : str or `None` is the name
of the local file cache. If None, will default to the md5 hash or the url
(which incorporates the ticker and date range) Examples -------- >>> sp =
f.quotes_historical_yahoo_ochl('^GSPC', d1, d2, asobject=True,
adjusted=True) >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] >>>
[n,bins,patches] = hist(returns, 100) >>> mu = mean(returns) >>> sigma =
std(returns) >>> x = normpdf(bins, mu, sigma) >>> plot(bins, x,
color='red', lw=2)

Thank you very much!

On Fri, Aug 25, 2017 at 1:01 PM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 25/08/17 15:19, C W wrote:
> > I did not mean to leave out the error message, it was very long.
>
> That just means it has a lot of information in it :-)
>
> >  I think the package has been removed.
>
> I don;t think so based on the traceback...
>
> >>>> quotes = quotes_historical_yahoo_ochl('APX', start, ... )
> > ------------------------------
> > TypeError: quotes_historical_yahoo_ochl() missing 1 required positional
> > argument: 'date2'
>
> Did you check what parameters were required for this function?
> The error says you are missing one.
>
> > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
>
> Note the filename. That suggests finance.py is still there.
>
> > quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted,
> > cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2,
> > asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413
> > ochl=True) 414 415
> > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in
> > _quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted,
> > cachename, ochl) 501 # warnings.warn("Recommend changing to
> asobject=None")
> > 502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename)
> 504
> > 505 try:
>
> Some warnings there that might be relevant, I don't know
> anything about the package or function.
>
> You could try running the help() function:
>
> >>> help(quotes_historical_yahoo_ochl)
>
> And see if it shows anything useful.
>
> --
> 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
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From robertvstepp at gmail.com  Sat Aug 26 22:27:12 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 26 Aug 2017 21:27:12 -0500
Subject: [Tutor] Best way to get root project directory in module search path
Message-ID: <CANDiX9+ZDjuTFUdNWfDRdgTShFAO3bZuNOUaM0Y_Q2BCVWah5Q@mail.gmail.com>

SunOS 5.10, Python 2.4/2.6.  Again, please forgive any typos as I am
having to manually enter everything.

I must confess that even though I've asked about similar topics in the
past, I still don't think I'm fully "getting it".

I have a project structure where I am developing various programs,
some in Pinnacle HotScript language, some in Perl, some in Python,
some shell scripts.  For the purpose of this question, my simplified
development file structure is:

~/_dev_Scripts
    /ScriptMenuSystem
        __init__.py
        test.py

    /py_utilities
        __init__.py
        test.py

When I am fully happy (Not really! ~(:>)) ) with everything I will
copy everything pertinent from "~_dev_Scripts" into a location like
"/usr/local/.../Scripts/boB_Scripts".  So all code must be able to
handle any change in location from where I am developing it.  On to my
difficulties ...

ScriptMenuSystem/test.py:

-------------------------------------------------
#!/usr/bin/env python

import sys
sys.path.append('..')

import py_utilities.test as t

t.test_print()
-------------------------------------------------

py_utilities/test.py:

-------------------------------------------------
#!/usr/bin/env python

def test_print():
    print 'This is module test.py!'
-------------------------------------------------

And when I run the first script from the ScriptMenuSystem location:

> python test.py
This is module test.py!

So, this works, but seems clunky to me.  I do not want to set
PYTHONPATH as that would only help me, not the other people who will
be using my programs.  I have read of including a .pth file with a
contained list of locations that should be part of the module search
path, but is this the best way for my use case?  And can it be written
in such a way that I do not have to edit it when I copy and move the
code to its new location?  As I already have these empty __init__.py
files, is there something I can add to these files to solve the
situation and make the project root directory part of the module
search path?

TIA!

-- 
boB

From robertvstepp at gmail.com  Sat Aug 26 22:29:20 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 26 Aug 2017 21:29:20 -0500
Subject: [Tutor] How to use subprocess module to get current logged in
 user?
In-Reply-To: <onr7gv$7cj$1@blaine.gmane.org>
References: <CANDiX9+_iHHdBdpdA__iUTQnT-HusO_dL3Jmrz=nBkFYSmrstw@mail.gmail.com>
 <onr7gv$7cj$1@blaine.gmane.org>
Message-ID: <CANDiX9LBNL-eWyT5ahAKm_-NE6cc1APN1gpVhnE-XTM3nBY2mg@mail.gmail.com>

Thanks Alan (and Mats)!  It appears there are many ways to skin this cat!

On Sat, Aug 26, 2017 at 2:21 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
>
>> My objective:  Determine who the currently logged in user is and
>> determine if that user is in my list of users that I have authorized
>> to use my programs.
>
> In addition to Steve and Mats answers:
>
> import os
> os.getlogin()   #-> 'alan'
> os.getuid() #-> 1001
>
> import pwd
> pwd.getpwuid(os.getuid()) #-> loads of user related stuff...
>
> You can also use the environment variables such as
>
> os.getenv('USER') #-> 'alan'
> os.getenv('HOME') #-> '/home/alan'
>
> the latter being a useful place to look for the
> individual config file... You can use os.environ
> if you prefer a dictionary style to a function.
>
> And of course
>
> os.cwd() #-> '/home/alan'
>
> For the current directory.


-- 
boB

From gsconyer at yahoo.com  Sat Aug 26 22:07:30 2017
From: gsconyer at yahoo.com (George Sconyers)
Date: Sun, 27 Aug 2017 02:07:30 +0000 (UTC)
Subject: [Tutor] easygui
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
Message-ID: <1454183736.1580070.1503799650710@mail.yahoo.com>

Hello all. Need some help with easygui which my son is trying to run for a book he is working in. Using Python 2.7 we downloaded easygui and put it in an executable path.?
Code is:import easyguieasygui.msgbox("Hello there")
No popup occurs, cusor changes to a cross and no longer process mouse clicks. When we click on the bash shell the program terminates, cursor returns to normal, and the following error is delivered:
script.py: line 2: syntax error near unexpected token ?'"Hello there"'script.py: line 2: 'easygui.msgbox("Hello there")'
We also tried:import easyguimsgbox("Hello there")
Returns the error message:script.py: line 2: syntax error near unexpected token ?'"Hello there"'script.py: line 2: 'msgbox("Hello there")'
Checked on "easygui. sourceforge. net/tutorial.html#msgbox" and it appears I am using the correct syntax. Probably a stupid mistake but I am stumped.?
ThanksGeorge

Sent from Yahoo Mail for iPhone

From alan.gauld at yahoo.co.uk  Sun Aug 27 04:14:58 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 27 Aug 2017 09:14:58 +0100
Subject: [Tutor] easygui
In-Reply-To: <1454183736.1580070.1503799650710@mail.yahoo.com>
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <1454183736.1580070.1503799650710@mail.yahoo.com>
Message-ID: <ontv1q$g1g$1@blaine.gmane.org>

On 27/08/17 03:07, George Sconyers via Tutor wrote:
> Hello all. Need some help with easygui which my son is trying to run for a book he is working in.

I'm not sure what the current status of easygui is, I read
somewhere that it had been discontinued. But if you are
still finding a download for 2.7 then it should
presumably work... Ok, I see that the code is still
available, and being Tkinter based should still work
but the project was frozen in 2013.

> Using Python 2.7 we downloaded easygui and put it in an executable path. 
> Code is:import easyguieasygui.msgbox("Hello there")

The code appears to be mangled by the mail system. I assume you mean

import easygui
easygui.msgbox("Hello there")

> No popup occurs, cusor changes to a cross and no longer process mouse clicks.> When we click on the bash shell the program terminates,

I assume from the bash reference that you are using either Linux
or MacOSX?

> script.py: line 2: syntax error near unexpected token  '"Hello there"
> 'script.py: line 2: 'easygui.msgbox("Hello there")'

How exactly are you running the program?
The message format does not look like a normal Python
traceback message.

BTW you can do very similar style coding to easygui using
raw Tkinter. You need to add the following 4 lines at the
top of your file (this is for Python v3):

import tkinter
import tkinter.messagebox as mb
tk = tkinter.Tk()
tk.withdraw()    # hide the default blank window

Now you can use the various message boxes etc in a
very similar style to easygui:

mb.showinfo("Title here", "Text here")
mb.askyesno("Title", "Are you well?")

dir(mb)

will show the other options available.
You can also import tkinter.filedialog,colorchooser and font.

Just in case you can't get easygui to work.

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



From cs at cskk.id.au  Sun Aug 27 03:13:21 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 27 Aug 2017 17:13:21 +1000
Subject: [Tutor] Best way to get root project directory in module search
 path
In-Reply-To: <CANDiX9+ZDjuTFUdNWfDRdgTShFAO3bZuNOUaM0Y_Q2BCVWah5Q@mail.gmail.com>
References: <CANDiX9+ZDjuTFUdNWfDRdgTShFAO3bZuNOUaM0Y_Q2BCVWah5Q@mail.gmail.com>
Message-ID: <20170827071321.GA20173@cskk.homeip.net>

On 26Aug2017 21:27, boB Stepp <robertvstepp at gmail.com> wrote:
>I have a project structure where I am developing various programs,
>some in Pinnacle HotScript language, some in Perl, some in Python,
>some shell scripts.  For the purpose of this question, my simplified
>development file structure is:
>
>~/_dev_Scripts
>    /ScriptMenuSystem
>        __init__.py
>        test.py
>
>    /py_utilities
>        __init__.py
>        test.py
>
>When I am fully happy (Not really! ~(:>)) ) with everything I will
>copy everything pertinent from "~_dev_Scripts" into a location like
>"/usr/local/.../Scripts/boB_Scripts".  So all code must be able to
>handle any change in location from where I am developing it.  On to my
>difficulties ...
>
>ScriptMenuSystem/test.py:
>
>-------------------------------------------------
>#!/usr/bin/env python
>
>import sys
>sys.path.append('..')
>
>import py_utilities.test as t
>
>t.test_print()

The trouble with this specific approach is that '..' relies on your _working_ 
directory being above ScriptMenuSystem i.e. the directory you shell's in; '..' 
is not related to the path to the test.py file. What yu want for this is the 
actual path to the code i.e. __file__.  Eg:

  sys.path.append(dirname(dirname(__file__)))

but that requires your module to know its own location within your library i.e.  
that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore that you 
want .../dev_scripts. Fragile. (And __file__ doesn't work in some more arcane 
ways of distributing modules, such as in zip files but let's not go there, not 
least because I've never done that myself).

The usual approach is to burden the user of the module. They're using it: 
ideally they have "installed" it by putting it somewhere sensible. So in a 
sense you should be able to rely on $PYTHONPATH already being set up.

Think about the end game: supposing people are using your modules in some 
larger system (eg a virtualenv). Do they really even _want_ you mucking about 
with their $PYTHONPATH or sys.path or, really, anything that will affect how 
modules are looked up?

Personally, I rely on $PYTHONPATH being right when I'm called. If someone's 
"installed" your module (eg by putting it in site-packages or wherever) the 
path is already set up. For my development purposes I invoke my code via a 
"dev" shell function which prehacks $PYTHONPATH to have my local lib directory 
at the start of $PYTHONPATH. Again, the module itself can then trust that 
things are as they should be. Which is as it should be.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From mats at wichmann.us  Sun Aug 27 09:18:03 2017
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 27 Aug 2017 07:18:03 -0600
Subject: [Tutor] easygui
In-Reply-To: <ontv1q$g1g$1@blaine.gmane.org>
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <1454183736.1580070.1503799650710@mail.yahoo.com>
 <ontv1q$g1g$1@blaine.gmane.org>
Message-ID: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>

On 08/27/2017 02:14 AM, Alan Gauld via Tutor wrote:
> On 27/08/17 03:07, George Sconyers via Tutor wrote:
>> Hello all. Need some help with easygui which my son is trying to run for a book he is working in.
> 
> I'm not sure what the current status of easygui is, I read
> somewhere that it had been discontinued. But if you are
> still finding a download for 2.7 then it should
> presumably work... Ok, I see that the code is still
> available, and being Tkinter based should still work
> but the project was frozen in 2013.
> 
>> Using Python 2.7 we downloaded easygui and put it in an executable path. 
>> Code is:import easyguieasygui.msgbox("Hello there")
> 
> The code appears to be mangled by the mail system. I assume you mean
> 
> import easygui
> easygui.msgbox("Hello there")
> 
>> No popup occurs, cusor changes to a cross and no longer process mouse clicks.> When we click on the bash shell the program terminates,
> 
> I assume from the bash reference that you are using either Linux
> or MacOSX?
> 
>> script.py: line 2: syntax error near unexpected token  '"Hello there"
>> 'script.py: line 2: 'easygui.msgbox("Hello there")'
> 
> How exactly are you running the program?
> The message format does not look like a normal Python
> traceback message.

Indeed, that's an error from bash running the script, not Python.

If you're on Linux (or Mac), and your script is named example.py, run it as:

python example.py

or perhaps less intuitively, stick a first line in it to tell the system
to have Python run it, so your script looks like this (there are
possible variants on that magic first line, but this one should work
whichever your platform is, as long as it is the first line):

#!/usr/bin/env python
import easygui
easygui.msgbox("Hello there")


and you can then run the script directly.


From robertvstepp at gmail.com  Sun Aug 27 15:27:57 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 27 Aug 2017 14:27:57 -0500
Subject: [Tutor] Best way to get root project directory in module search
 path
In-Reply-To: <20170827071321.GA20173@cskk.homeip.net>
References: <CANDiX9+ZDjuTFUdNWfDRdgTShFAO3bZuNOUaM0Y_Q2BCVWah5Q@mail.gmail.com>
 <20170827071321.GA20173@cskk.homeip.net>
Message-ID: <CANDiX9+Ot0nzH-vO20+F5JKRNLcj-sU-rOr0aTejsJ6fj5TCVg@mail.gmail.com>

On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson <cs at cskk.id.au> wrote:
> On 26Aug2017 21:27, boB Stepp <robertvstepp at gmail.com> wrote:
>>
>> I have a project structure where I am developing various programs,
>> some in Pinnacle HotScript language, some in Perl, some in Python,
>> some shell scripts.  For the purpose of this question, my simplified
>> development file structure is:
>>
>> ~/_dev_Scripts
>>    /ScriptMenuSystem
>>        __init__.py
>>        test.py
>>
>>    /py_utilities
>>        __init__.py
>>        test.py
>>
>> When I am fully happy (Not really! ~(:>)) ) with everything I will
>> copy everything pertinent from "~_dev_Scripts" into a location like
>> "/usr/local/.../Scripts/boB_Scripts".  So all code must be able to
>> handle any change in location from where I am developing it.  On to my
>> difficulties ...
>>
>> ScriptMenuSystem/test.py:
>>
>> -------------------------------------------------
>> #!/usr/bin/env python
>>
>> import sys
>> sys.path.append('..')
>>
>> import py_utilities.test as t
>>
>> t.test_print()
>
>
> The trouble with this specific approach is that '..' relies on your
> _working_ directory being above ScriptMenuSystem i.e. the directory you
> shell's in; '..' is not related to the path to the test.py file. What yu
> want for this is the actual path to the code i.e. __file__.  Eg:
>
>  sys.path.append(dirname(dirname(__file__)))

I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the
other 2.6) and got the following:

Traceback (most recent call last):
    File "... /test.py", line 9, in <module>
        sys.path.append(dirname(dirname(__file__)))
NameError:  name 'dirname' is not defined

Is this a version issue or do I have the syntax wrong?

Anyway, I tried something a bit different that implemented this:

pgm_dir = os.path.dirname(os.path.abspath(__file__))
pgm_root = pgm_dir.replace('/ScriptMenuSystem', '')
sys.path.append(pgm_root)

And this gave me the results I wanted.  Funny that 'dirname' works
with os.path but not with sys.path.

BTW, I have not used os.walk yet, but would that be better than my bit
of string manipulation above?  If yes, an example of walking up and
getting the directory exactly one level up from __file__ would be
appreciated.

> but that requires your module to know its own location within your library
> i.e.  that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore
> that you want .../dev_scripts. Fragile. (And __file__ doesn't work in some
> more arcane ways of distributing modules, such as in zip files but let's not
> go there, not least because I've never done that myself).

I have been using the same project structure for some years now, so in
that sense it is well-established and not fragile.  I don't anticipate
it changing.  There is actually no installation in a traditional
sense.  Once I develop something worth using, it gets copied (by me as
root) from my user area to an accessible location to those users that
requested access.  I had been doing this copying to each user's area,
but that has grown unwieldy as my couple of users have grown into
around 15.  So I am moving to put everything in a centrally accessible
location and will probably adopt Steve's suggestion to establish a
group with permissions to use these programs.

So I think this idea (Or some variation thereof.) is what I need to
do.  Or the good experts here show me I'm engaged in foolishness!

Cheers!


-- 
boB

From cs at cskk.id.au  Sun Aug 27 19:03:43 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 28 Aug 2017 09:03:43 +1000
Subject: [Tutor] Best way to get root project directory in module search
 path
In-Reply-To: <CANDiX9+Ot0nzH-vO20+F5JKRNLcj-sU-rOr0aTejsJ6fj5TCVg@mail.gmail.com>
References: <CANDiX9+Ot0nzH-vO20+F5JKRNLcj-sU-rOr0aTejsJ6fj5TCVg@mail.gmail.com>
Message-ID: <20170827230343.GA95280@cskk.homeip.net>

On 27Aug2017 14:27, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson <cs at cskk.id.au> wrote:
>> On 26Aug2017 21:27, boB Stepp <robertvstepp at gmail.com> wrote:
>>> import sys
>>> sys.path.append('..')
[...]
>> The trouble with this specific approach is that '..' relies on your
>> _working_ directory being above ScriptMenuSystem i.e. the directory you
>> shell's in; '..' is not related to the path to the test.py file. What yu
>> want for this is the actual path to the code i.e. __file__.  Eg:
>>
>>  sys.path.append(dirname(dirname(__file__)))
>
>I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the
>other 2.6) and got the following:
>
>Traceback (most recent call last):
>    File "... /test.py", line 9, in <module>
>        sys.path.append(dirname(dirname(__file__)))
>NameError:  name 'dirname' is not defined

from os.path import dirname

>Is this a version issue or do I have the syntax wrong?

Just a missing import. You'll find dirname in the Index section of the Python 
docs. Handy for locating something just mentioned.

>Anyway, I tried something a bit different that implemented this:
>
>pgm_dir = os.path.dirname(os.path.abspath(__file__))
>pgm_root = pgm_dir.replace('/ScriptMenuSystem', '')
>sys.path.append(pgm_root)

Calling os.path.dirname a second time does what your:

  pgm_dir.replace('/ScriptMenuSystem', '')

does, but reliably. Supposing you have the misfortune to have 
'/ScriptMenuSystem' higher up in the full path also? Supposing your package 
changes its name in the future, or is installed with another name? Fragility.

>And this gave me the results I wanted.  Funny that 'dirname' works
>with os.path but not with sys.path.

No no. "dirname" comes from the "os.path" module. That is all.

>BTW, I have not used os.walk yet, but would that be better than my bit
>of string manipulation above?  If yes, an example of walking up and
>getting the directory exactly one level up from __file__ would be
>appreciated.

Well:

  from os.path import abspath, dirname, join
  code_dir = abspath(join(dirname(__file), '..'))

or:

  from os.path import abspath, dirname, join
  code_dir = abspath(join(dirname(__file), '../..'))

depending how high you want to go.

Given that os.walk walks _down_ the tree from some directory, how do you think 
it would help you?

>> but that requires your module to know its own location within your library
>> i.e.  that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore
>> that you want .../dev_scripts. Fragile. (And __file__ doesn't work in some
>> more arcane ways of distributing modules, such as in zip files but let's not
>> go there, not least because I've never done that myself).
>
>I have been using the same project structure for some years now, so in
>that sense it is well-established and not fragile.

It is more that embedded specific hardwired knowledge in the code is an 
inherently fragile situation, if only because it must be remembered when naming 
changes occur. And they do. I have a quite large package I've been working on 
for a decade and am very seriously contemplating changing its name in the next 
month or so. Fortunately the installed base is small.

>I don't anticipate
>it changing.  There is actually no installation in a traditional
>sense.  Once I develop something worth using, it gets copied (by me as
>root) from my user area to an accessible location to those users that
>requested access.  I had been doing this copying to each user's area,
>but that has grown unwieldy as my couple of users have grown into
>around 15.

For simple packages/modules an install _is_ just a copy. So you're performing 
the install step.

>So I am moving to put everything in a centrally accessible
>location

Very sound. But to use it your users should have that location as part of their 
python path, or the code needs to be invoked by some wrapper which can insert 
the needed path. Both these things live _outside_ the package code.

>and will probably adopt Steve's suggestion to establish a
>group with permissions to use these programs.

Note that this is normally only needed for code that is privileged i.e. runs 
with permissions different to those of the user.

>So I think this idea (Or some variation thereof.) is what I need to
>do.  Or the good experts here show me I'm engaged in foolishness!

I think you're better off arranging your users' environments to include the 
shared library area, or providing a wrapper shell script which does that and 
then invokes the real code.

Eg:

  #!/bin/sh
  PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH
  export PYTHONPATH
  python -m your.module.name ${1+"$@"}

Such a script has the advantage that the $PYTHONPATH change applies only to the 
python running your module, not to your users' wider environment.

Cheers,
Cameron Simpson <cs at cskk.id.au>

From anubhav.yadav at gmx.com  Sun Aug 27 16:21:18 2017
From: anubhav.yadav at gmx.com (Anubhav Yadav)
Date: Mon, 28 Aug 2017 01:51:18 +0530
Subject: [Tutor] Need advice on testing python code.
Message-ID: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>

Hello.

I am a python developer and I write a lot of python code everyday. I try to do as much unit testing as possible. But I want to be better at it, I want to write more test cases, specially that rely on database insertions and reads and file io. Here are my use-cases for testing. 
How to test if things are going into the database properly or not? (mysql/mongo). I want to be able to create a test database environment as simple as possible. Create and delete the test environment before each functional test case is run. 
Sometimes I write code that read some data from some rabbitmq queue and do certain things. How can I write end to end functional test that creates a test rabbitmq environment (exchanges and queues) -> wait for sometime -> see if the intended work has been done -> delete the test environment. 
I want to be able to make sure that any new commit on my self hosted gitlab server should first run all functional test cases first before accepting the merge. 
Since we use lot of docker here to deploy modules to productions, I want to write functional test cases that test the whole system as a whole and see if things are happening the way they are supposed to happen or not. This means firing up lot of docker containers, lot of test databases with some data, and run all the test cases from an end user point of view. 
Can you suggest me the right python testing frameworks that I should be using? Right now I am using unittest to write test cases and manual if/else statements to run the functional test cases. 
I try to create rabbitmq queues and bind them to rabbitmq exchanges using the pika module. I then run the module using python -m moduleName and then sleep for sometime. Then I kill the processs (subprocess) and then I see if the intended consequences have happened or not. It's a pain in the ass to be doing so many things for test cases. I clearly need to learn how to do things better. 
Any suggestion/book/article/course/video will help me immensely in becoming a developer who writes better code with lot of test cases. 

Thanks for reading. 

From gsconyer at yahoo.com  Sun Aug 27 13:21:54 2017
From: gsconyer at yahoo.com (George Sconyers)
Date: Sun, 27 Aug 2017 17:21:54 +0000 (UTC)
Subject: [Tutor] Fw:  easygui
In-Reply-To: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <1454183736.1580070.1503799650710@mail.yahoo.com>
 <ontv1q$g1g$1@blaine.gmane.org>
 <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>
Message-ID: <1590800081.1750357.1503854514290@mail.yahoo.com>

Mats, that first line was the problem.
Alan, I like the Tkinter idea. Had to pull that package for easygui to work. I will look at transitioning once my son works through the easygui chapter. Trying to teach him how to learn as much as how to program.?
Thank you both!?George






From tmrsg11 at gmail.com  Sun Aug 27 14:29:30 2017
From: tmrsg11 at gmail.com (C W)
Date: Sun, 27 Aug 2017 14:29:30 -0400
Subject: [Tutor] What exactly does the three dots do? Why such as thing?
In-Reply-To: <20170812012405.GL7395@ando.pearwood.info>
References: <CAE2FW2=AaXoPgCwqONOZg6ScQboWcURz_2e2BnskNgkhY8==gQ@mail.gmail.com>
 <20170810124759.GC7395@ando.pearwood.info>
 <CAE2FW2m782WSew2_-LSnd8SP6YJau8hNGqTG2RaQD=8wNF5NBg@mail.gmail.com>
 <omiptr$mg2$1@blaine.gmane.org>
 <b731bdb9-99a5-4e2b-ddca-2b75209a20b0@wichmann.us>
 <20170812012405.GL7395@ando.pearwood.info>
Message-ID: <CAE2FW2mjMG7u_mwpjC2=Ytna6BPPyLeoHZy34+G4rvZf5S9x2A@mail.gmail.com>

Today, I ran into ellipsis again. This time, it is COMPLETELY different
from before.

Here is a reproducible code:

import numpy as np
import matplotlib.pyplot as plt
...
x = np.linspace(0, 1)
y = np.sin(4 * np.pi * x) * np.exp(-5 * x)
plt.title('Week cycle')
plt.xlabel('Month')
plt.ylabel('Price')
plt.plot(x, y)


If I leave out the ellipsis, plot title and label will not show. It's doing
interactive plot. How am I suppose to know ellipsis is doing interactive
plotting? No way I could have guessed.

Matplotlib documentation <https://matplotlib.org/> explains that it
recreated itself from Matlab plots.

Is it something similar to Matlab like
>>> hold on;

That's fine! But, how many identities will ellipsis take on? How do you
experienced users deal with these ambiguities?



On Fri, Aug 11, 2017 at 9:24 PM, Steven D'Aprano <steve at pearwood.info>
wrote:

> On Fri, Aug 11, 2017 at 07:57:09AM -0600, Mats Wichmann wrote:
> > On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote:
> > > On 10/08/17 14:39, C W wrote:
> > >
> > >> I suppose it's just a place holder, though I don't know when I would
> use it
> > >> in my every day life.
> > >
> > > Probably never.
> > >
> > > Like most programming languages Python has a load of rarely used,
> > > obscure features. Most Python programmers never use ellipses,
> >
> > I guess what this means is when I post code snippets with some lines
> > elided for greater readability of the point being made I should not use
> > ellipses for that, as they're actually a syntactic element!   :)
>
> No, go right ahead and continue using ... for elided lines. Python 3
> makes that syntactically legal, and the fact that elided code may be
> syntactically correct is one of the reasons that was done.
>
> In Python 2, ... was just the *display* form of Ellipsis, and wasn't
> legal except in slice notation: a[...]. Python 3 made ... syntactic
> sugar for Ellipse everywhere, not just in slices, which makes:
>
>     x = ...
>
>     class X:
>         ...
>
> perfectly legal code. (Perhaps not *meaningful* code, but that's okay.)
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From anubhav.yadav at gmx.com  Mon Aug 28 03:43:31 2017
From: anubhav.yadav at gmx.com (Anubhav Yadav)
Date: Mon, 28 Aug 2017 13:13:31 +0530
Subject: [Tutor] Need advice on testing python code.
In-Reply-To: <CAFwcP0i1daAPTkgYCSC-cu3abuHjOX+AnaWOoZjF9K+s8bppcQ@mail.gmail.com>
References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
 <CAFwcP0i1daAPTkgYCSC-cu3abuHjOX+AnaWOoZjF9K+s8bppcQ@mail.gmail.com>
Message-ID: <D7F82F00-80E3-49CC-933B-6815854C820B@gmx.com>

Hi George, 

> And pytest has more than 200 plugins to make it easier to test things. As I remember it has mongo plugin as we well
> 

Thank you for your comments. 

I have been using `py.test` for only two reasons.

1. To run my tests places in the `<project>/tests` directory. 
2. To run them whenever I save any file int he project using `py.test -f` (after installing pytest-xdist plugin). 

I will have a look at py.test again and look at examples. This is a great start for me. 

I usually work with writing APIs using Flask, which I test using `fixtures` and `mock`. I also write a lot of code which interacts with a lot of external modules like
`rabbitmq`, `databases` etc. I want to be better at write maybe integration tests and functional tests. 

If you have any more advice regarding those please let me know. Any recommended reading would help immensely. 

- Anubhav. 





From george at fischhof.hu  Mon Aug 28 02:03:32 2017
From: george at fischhof.hu (George Fischhof)
Date: Mon, 28 Aug 2017 08:03:32 +0200
Subject: [Tutor] Need advice on testing python code.
In-Reply-To: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
Message-ID: <CAFwcP0i+=6ofoabYfP1Dcf-uGkziJx1z0VeDHbGjnOmS-xffBQ@mail.gmail.com>

2017. aug. 28. 2:15 ezt ?rta ("Anubhav Yadav" <anubhav.yadav at gmx.com>):

Hello.

I am a python developer and I write a lot of python code everyday. I try to
do as much unit testing as possible. But I want to be better at it, I want
to write more test cases, specially that rely on database insertions and
reads and file io. Here are my use-cases for testing.
How to test if things are going into the database properly or not?
(mysql/mongo). I want to be able to create a test database environment as
simple as possible. Create and delete the test environment before each
functional test case is run.
Sometimes I write code that read some data from some rabbitmq queue and do
certain things. How can I write end to end functional test that creates a
test rabbitmq environment (exchanges and queues) -> wait for sometime ->
see if the intended work has been done -> delete the test environment.
I want to be able to make sure that any new commit on my self hosted gitlab
server should first run all functional test cases first before accepting
the merge.
Since we use lot of docker here to deploy modules to productions, I want to
write functional test cases that test the whole system as a whole and see
if things are happening the way they are supposed to happen or not. This
means firing up lot of docker containers, lot of test databases with some
data, and run all the test cases from an end user point of view.
Can you suggest me the right python testing frameworks that I should be
using? Right now I am using unittest to write test cases and manual if/else
statements to run the functional test cases.
I try to create rabbitmq queues and bind them to rabbitmq exchanges using
the pika module. I then run the module using python -m moduleName and then
sleep for sometime. Then I kill the processs (subprocess) and then I see if
the intended consequences have happened or not. It's a pain in the ass to
be doing so many things for test cases. I clearly need to learn how to do
things better.
Any suggestion/book/article/course/video will help me immensely in becoming
a developer who writes better code with lot of test cases.

Thanks for reading.
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



Hi Anubhav,

I think, pytest will be good for you
https://docs.pytest.org/en/latest/contents.html

BR
George

From george at fischhof.hu  Mon Aug 28 02:06:00 2017
From: george at fischhof.hu (George Fischhof)
Date: Mon, 28 Aug 2017 08:06:00 +0200
Subject: [Tutor] Need advice on testing python code.
In-Reply-To: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
Message-ID: <CAFwcP0i1daAPTkgYCSC-cu3abuHjOX+AnaWOoZjF9K+s8bppcQ@mail.gmail.com>

2017. aug. 28. de. 2:15 ezt ?rta ("Anubhav Yadav" <anubhav.yadav at gmx.com>):

Hello.

I am a python developer and I write a lot of python code everyday. I try to
do as much unit testing as possible. But I want to be better at it, I want
to write more test cases, specially that rely on database insertions and
reads and file io. Here are my use-cases for testing.
How to test if things are going into the database properly or not?
(mysql/mongo). I want to be able to create a test database environment as
simple as possible. Create and delete the test environment before each
functional test case is run.
Sometimes I write code that read some data from some rabbitmq queue and do
certain things. How can I write end to end functional test that creates a
test rabbitmq environment (exchanges and queues) -> wait for sometime ->
see if the intended work has been done -> delete the test environment.
I want to be able to make sure that any new commit on my self hosted gitlab
server should first run all functional test cases first before accepting
the merge.
Since we use lot of docker here to deploy modules to productions, I want to
write functional test cases that test the whole system as a whole and see
if things are happening the way they are supposed to happen or not. This
means firing up lot of docker containers, lot of test databases with some
data, and run all the test cases from an end user point of view.
Can you suggest me the right python testing frameworks that I should be
using? Right now I am using unittest to write test cases and manual if/else
statements to run the functional test cases.
I try to create rabbitmq queues and bind them to rabbitmq exchanges using
the pika module. I then run the module using python -m moduleName and then
sleep for sometime. Then I kill the processs (subprocess) and then I see if
the intended consequences have happened or not. It's a pain in the ass to
be doing so many things for test cases. I clearly need to learn how to do
things better.
Any suggestion/book/article/course/video will help me immensely in becoming
a developer who writes better code with lot of test cases.

Thanks for reading.
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



And pytest has more than 200 plugins to make it easier to test things. As I
remember it has mongo plugin as we well

George

From george at fischhof.hu  Mon Aug 28 04:20:50 2017
From: george at fischhof.hu (George Fischhof)
Date: Mon, 28 Aug 2017 10:20:50 +0200
Subject: [Tutor] Need advice on testing python code.
In-Reply-To: <D7F82F00-80E3-49CC-933B-6815854C820B@gmx.com>
References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
 <CAFwcP0i1daAPTkgYCSC-cu3abuHjOX+AnaWOoZjF9K+s8bppcQ@mail.gmail.com>
 <D7F82F00-80E3-49CC-933B-6815854C820B@gmx.com>
Message-ID: <CAFwcP0hgBWo8kukZ8HUb2nYS2mjAXod7vNKgohvUcQC=q_y9VQ@mail.gmail.com>

2017-08-28 9:43 GMT+02:00 Anubhav Yadav <anubhav.yadav at gmx.com>:

> Hi George,
>
> > And pytest has more than 200 plugins to make it easier to test things.
> As I remember it has mongo plugin as we well
> >
>
> Thank you for your comments.
>
> I have been using `py.test` for only two reasons.
>
> 1. To run my tests places in the `<project>/tests` directory.
> 2. To run them whenever I save any file int he project using `py.test -f`
> (after installing pytest-xdist plugin).
>
> I will have a look at py.test again and look at examples. This is a great
> start for me.
>
> I usually work with writing APIs using Flask, which I test using
> `fixtures` and `mock`. I also write a lot of code which interacts with a
> lot of external modules like
> `rabbitmq`, `databases` etc. I want to be better at write maybe
> integration tests and functional tests.
>
> If you have any more advice regarding those please let me know. Any
> recommended reading would help immensely.
>
> - Anubhav.
>
>


Here is the compatibility list of plugins:
http://plugincompat.herokuapp.com/

here is the rabbitmq plugin:
https://pypi.python.org/pypi/pytest-rabbitmq

and here is one for databases:
https://pypi.python.org/pypi/pytest-sqlalchemy/0.1

docker
https://pypi.python.org/pypi/pytest-docker/0.6.0


And if you do not have a CI system yet, then the buildbot CI can be good
for you
https://buildbot.net/
which is written in Python (and of course you manage it in Python)
(used by Python, Mozilla, Chrome etc)


George

From eriic1 at cox.net  Sun Aug 27 19:46:00 2017
From: eriic1 at cox.net (eric)
Date: Sun, 27 Aug 2017 16:46:00 -0700
Subject: [Tutor] easygui
In-Reply-To: <27jh1w00G3quhQC017jiRp>
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <27jh1w00G3quhQC017jiRp>
Message-ID: <604fbdd2-2252-ac99-9766-d23c574543c7@cox.net>

On 08/26/2017 07:07 PM, George Sconyers via Tutor wrote:
> Hello all. Need some help with easygui which my son is trying to run for a book he is working in. Using Python 2.7 we downloaded easygui and put it in an executable path.
> Code is:import easyguieasygui.msgbox("Hello there")
> No popup occurs, cusor changes to a cross and no longer process mouse clicks. When we click on the bash shell the program terminates, cursor returns to normal, and the following error is delivered:
> script.py: line 2: syntax error near unexpected token  '"Hello there"'script.py: line 2: 'easygui.msgbox("Hello there")'
> We also tried:import easyguimsgbox("Hello there")
> Returns the error message:script.py: line 2: syntax error near unexpected token  '"Hello there"'script.py: line 2: 'msgbox("Hello there")'
> Checked on "easygui. sourceforge. net/tutorial.html#msgbox" and it appears I am using the correct syntax. Probably a stupid mistake but I am stumped.
> ThanksGeorge
> 
> Sent from Yahoo Mail for iPhone
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

I tried it on Ubuntu 16.04 using python 2.7 and easygui version .96-3.

It worked for me using the following code in idle but should also work 
in the python interpreter shell:

Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "copyright", "credits" or "license()" for more information.
 >>> import easygui
 >>> easygui.msgbox("Hello There")
'OK'
 >>>

A popup box came up and I could press OK in the box and the box would 
disappear.

I wonder if you are running this in a text only environment and that is 
why the box is not showing up.

I am still a newbie when it comes to programming but I am willing to 
help if I can.

Good luck George,

Eric


From anubhav.yadav at gmx.com  Mon Aug 28 04:29:45 2017
From: anubhav.yadav at gmx.com (Anubhav Yadav)
Date: Mon, 28 Aug 2017 13:59:45 +0530
Subject: [Tutor] Need advice on testing python code.
In-Reply-To: <CAFwcP0hgBWo8kukZ8HUb2nYS2mjAXod7vNKgohvUcQC=q_y9VQ@mail.gmail.com>
References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com>
 <CAFwcP0i1daAPTkgYCSC-cu3abuHjOX+AnaWOoZjF9K+s8bppcQ@mail.gmail.com>
 <D7F82F00-80E3-49CC-933B-6815854C820B@gmx.com>
 <CAFwcP0hgBWo8kukZ8HUb2nYS2mjAXod7vNKgohvUcQC=q_y9VQ@mail.gmail.com>
Message-ID: <D0816961-49BF-4821-B07B-40D59F76F681@gmx.com>


> Here is the compatibility list of plugins:
> http://plugincompat.herokuapp.com/ <http://plugincompat.herokuapp.com/> 
> 
> here is the rabbitmq plugin:
> https://pypi.python.org/pypi/pytest-rabbitmq <https://pypi.python.org/pypi/pytest-rabbitmq>
> 
> and here is one for databases:
> https://pypi.python.org/pypi/pytest-sqlalchemy/0.1 <https://pypi.python.org/pypi/pytest-sqlalchemy/0.1>
> 
> docker
> https://pypi.python.org/pypi/pytest-docker/0.6.0 <https://pypi.python.org/pypi/pytest-docker/0.6.0>
> 
> 
> And if you do not have a CI system yet, then the buildbot CI can be good for you
> https://buildbot.net/ <https://buildbot.net/>
> which is written in Python (and of course you manage it in Python)
> (used by Python, Mozilla, Chrome etc)
> 

This is awesome George. 

Much appreciated. I think `pytest` will be my favourite testing tool in the python ecosystem going forward. 

Cheers. 


From robertvstepp at gmail.com  Mon Aug 28 21:39:02 2017
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 28 Aug 2017 20:39:02 -0500
Subject: [Tutor] Best way to get root project directory in module search
 path
In-Reply-To: <20170827230343.GA95280@cskk.homeip.net>
References: <CANDiX9+Ot0nzH-vO20+F5JKRNLcj-sU-rOr0aTejsJ6fj5TCVg@mail.gmail.com>
 <20170827230343.GA95280@cskk.homeip.net>
Message-ID: <CANDiX9L1fbOSGDzxi4=GhHJA7ZuYJOtzJy0ZxYpJDpAmGDdL0w@mail.gmail.com>

On Sun, Aug 27, 2017 at 6:03 PM, Cameron Simpson <cs at cskk.id.au> wrote:
> On 27Aug2017 14:27, boB Stepp <robertvstepp at gmail.com> wrote:
>>
>> On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson <cs at cskk.id.au> wrote:
>>>
>>> On 26Aug2017 21:27, boB Stepp <robertvstepp at gmail.com> wrote:

>>> The trouble with this specific approach is that '..' relies on your
>>> _working_ directory being above ScriptMenuSystem i.e. the directory you
>>> shell's in; '..' is not related to the path to the test.py file. What yu
>>> want for this is the actual path to the code i.e. __file__.  Eg:
>>>
>>>  sys.path.append(dirname(dirname(__file__)))
>>
>>
>> I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the
>> other 2.6) and got the following:
>>
>> Traceback (most recent call last):
>>    File "... /test.py", line 9, in <module>
>>        sys.path.append(dirname(dirname(__file__)))
>> NameError:  name 'dirname' is not defined
>
>
> from os.path import dirname

It did not occur to me to import something from os.path to use sys.path!


>> Anyway, I tried something a bit different that implemented this:
>>
>> pgm_dir = os.path.dirname(os.path.abspath(__file__))
>> pgm_root = pgm_dir.replace('/ScriptMenuSystem', '')
>> sys.path.append(pgm_root)
>
>
> Calling os.path.dirname a second time does what your:
>
>  pgm_dir.replace('/ScriptMenuSystem', '')
>
> does, but reliably. Supposing you have the misfortune to have
> '/ScriptMenuSystem' higher up in the full path also? Supposing your package
> changes its name in the future, or is installed with another name?
> Fragility.
>

>> BTW, I have not used os.walk yet, but would that be better than my bit
>> of string manipulation above?  If yes, an example of walking up and
>> getting the directory exactly one level up from __file__ would be
>> appreciated.

> Given that os.walk walks _down_ the tree from some directory, how do you
> think it would help you?

At https://docs.python.org/release/2.4.4/lib/os-file-dir.html it says:

"walk(top[, topdown=True [, onerror=None]])
walk() generates the file names in a directory tree, by walking the
tree either top down or bottom up."

So I thought I could go in either direction.

>> I have been using the same project structure for some years now, so in
>> that sense it is well-established and not fragile.
>
>
> It is more that embedded specific hardwired knowledge in the code is an
> inherently fragile situation, if only because it must be remembered when
> naming changes occur. And they do. I have a quite large package I've been
> working on for a decade and am very seriously contemplating changing its
> name in the next month or so. Fortunately the installed base is small.

I was working on removing the name dependencies.  So far I had the following:

import os
import sys

def set_project_root():
    pgm_dir = os.path.dirname(os.path.abspath(__filename__))
    dir_to_rmv = pgm_dir.split(os.sep)[-1]
    pgm_root = pgm_dir.replace(dir_to_rmv, '')
    sys.path.append(pgm_root)

But this only works if I only need to go up one level.  If I have
Python files more deeply nested in the project structure than this
won't work.  So I was pondering how I can do this for arbitrarily
deeply nested folders without relying on any specific naming.  I was
also wondering if this sort of code could be put in the __init__.py
files?  I have yet to do this latter experiment.

>> So I am moving to put everything in a centrally accessible
>> location
>
>
> Very sound. But to use it your users should have that location as part of
> their python path, or the code needs to be invoked by some wrapper which can
> insert the needed path. Both these things live _outside_ the package code.

Not being well-versed in Unix, is it possible to change the PYTHONPATH
*only* for a specific group of users and only for python programs in a
certain shared library area?  I will have to research this.  If
possible, this might indeed be the best way.

>> So I think this idea (Or some variation thereof.) is what I need to
>> do.  Or the good experts here show me I'm engaged in foolishness!
>
>
> I think you're better off arranging your users' environments to include the
> shared library area, or providing a wrapper shell script which does that and
> then invokes the real code.
>
> Eg:
>
>  #!/bin/sh
>  PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH
>  export PYTHONPATH
>  python -m your.module.name ${1+"$@"}
>
> Such a script has the advantage that the $PYTHONPATH change applies only to
> the python running your module, not to your users' wider environment.

This looks doable, though it complicates how I will call my python
programs.  These are always invoked by the Pinnacle HotScript
language.  Everything must start from within the Pinnacle planning
environment.


-- 
boB

From akleider at sonic.net  Mon Aug 28 23:03:29 2017
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 28 Aug 2017 21:03:29 -0600
Subject: [Tutor] easygui
In-Reply-To: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <1454183736.1580070.1503799650710@mail.yahoo.com>
 <ontv1q$g1g$1@blaine.gmane.org>
 <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>
Message-ID: <1d86903f5382a039651dee6603e8afdd@sonic.net>

On 2017-08-27 07:18, Mats Wichmann wrote:
> 
> 
> or perhaps less intuitively, stick a first line in it to tell the 
> system
> to have Python run it, so your script looks like this (there are
> possible variants on that magic first line, but this one should work
> whichever your platform is, as long as it is the first line):
> 
> #!/usr/bin/env python
> import easygui
> easygui.msgbox("Hello there")
> 
> 
> and you can then run the script directly.
> 

... After first adjusting permissions:

$ chmod 755 example,py


From cs at cskk.id.au  Mon Aug 28 22:59:29 2017
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 29 Aug 2017 12:59:29 +1000
Subject: [Tutor] Best way to get root project directory in module search
 path
In-Reply-To: <CANDiX9L1fbOSGDzxi4=GhHJA7ZuYJOtzJy0ZxYpJDpAmGDdL0w@mail.gmail.com>
References: <CANDiX9L1fbOSGDzxi4=GhHJA7ZuYJOtzJy0ZxYpJDpAmGDdL0w@mail.gmail.com>
Message-ID: <20170829025929.GA66001@cskk.homeip.net>

On 28Aug2017 20:39, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sun, Aug 27, 2017 at 6:03 PM, Cameron Simpson <cs at cskk.id.au> wrote:
>> from os.path import dirname
>It did not occur to me to import something from os.path to use sys.path!

It is pretty normal to import specific names from modules rather than 
laboriously writing things out like "os.path.dirname" everywhere. It makes code 
both easier to write and easier to read/maintain/debug.

[...]
>>> BTW, I have not used os.walk yet, but would that be better than my bit
>>> of string manipulation above?  If yes, an example of walking up and
>>> getting the directory exactly one level up from __file__ would be
>>> appreciated.
>
>> Given that os.walk walks _down_ the tree from some directory, how do you
>> think it would help you?
>
>At https://docs.python.org/release/2.4.4/lib/os-file-dir.html it says:
>
>"walk(top[, topdown=True [, onerror=None]])
>walk() generates the file names in a directory tree, by walking the
>tree either top down or bottom up."
>
>So I thought I could go in either direction.

Ah, no. It always walks down. The documentation is discussing in what order 
your call gets the results: upper directories before lower directories or the 
reverse.

>>> I have been using the same project structure for some years now, so in
>>> that sense it is well-established and not fragile.
>>
>> It is more that embedded specific hardwired knowledge in the code is an
>> inherently fragile situation, if only because it must be remembered when
>> naming changes occur. And they do. I have a quite large package I've been
>> working on for a decade and am very seriously contemplating changing its
>> name in the next month or so. Fortunately the installed base is small.
>
>I was working on removing the name dependencies.  So far I had the following:
>
>import os
>import sys
>
>def set_project_root():
>    pgm_dir = os.path.dirname(os.path.abspath(__filename__))
>    dir_to_rmv = pgm_dir.split(os.sep)[-1]
>    pgm_root = pgm_dir.replace(dir_to_rmv, '')
>    sys.path.append(pgm_root)
>
>But this only works if I only need to go up one level.  If I have
>Python files more deeply nested in the project structure than this
>won't work.  So I was pondering how I can do this for arbitrarily
>deeply nested folders without relying on any specific naming.  I was
>also wondering if this sort of code could be put in the __init__.py
>files?  I have yet to do this latter experiment.

If you really want to work this way you could start with dirname(__file__), and 
see if os.path.join(dirname(__file__), '__init__.py') exists. Keep going up 
until you find it. That will find the top of your particular package, and you 
might then presume that the level above that is a useful thing to add to 
sys.path.

But it still feels ... unreliable to me. I really do feel better requiring this 
setup to be correctly sorted before the module gets loaded.

Guessing/inferring where to find other modules (which is what hacking sys.path 
amounts to) is in my mind "policy". I like to keep policy separate from 
mechanism when I can. In this instance, my thinking is that sys.path is the 
mechanism, but deciding what to put in it is policy. Policy is for the caller, 
either directly or courtesy of some sysadmin "install" process.

When you put policy inside your code as an integral and worse, automatic, 
action you're overriding the caller's own policy. That might be bad.

>>> So I am moving to put everything in a centrally accessible
>>> location
>>
>> Very sound. But to use it your users should have that location as part of
>> their python path, or the code needs to be invoked by some wrapper which can
>> insert the needed path. Both these things live _outside_ the package code.
>
>Not being well-versed in Unix, is it possible to change the PYTHONPATH
>*only* for a specific group of users and only for python programs in a
>certain shared library area?  I will have to research this.  If
>possible, this might indeed be the best way.

Um, not very easily? The usual approach is instead to write a wrapper script.

The invoked Python program and everything it invokes will get any changes you 
make to the environment in the wrapper (environment variables such as 
$PYTHONPATH are automatically inhereited from a process to any of its children, 
absent special arrangments to the contrary).

But "programs" are invoked by executing something. You can stick your python 
modules where they belong, and have the programme be just the wrapper shell 
script which knows how to invoke them.

For example, I've got a small python module which has some knowledge about 
reading HAProxy configs and/or its status page, and the module has a command 
line mode (the main function, which would be in __main__ if it were a package - 
it is just a single module). I have a command called "haproxy-tool" for running 
that python function, and it is just a shell script wrapper, thus:

  #!/bin/sh
  exec py26+ -m cs.app.haproxy ${1+"$@"}

"py26+" is itself just a small script to find a python 2 which is at least 
python 2.6.

But you can see that its perfectly reasonable to make the "command" flavour of 
your python module a separate script, and you can put whatever preable you 
like, such as hacking $PYTHONPATH, into that script before it invokes the 
python interpreter.

[...]
>> I think you're better off arranging your users' environments to include the
>> shared library area, or providing a wrapper shell script which does that and
>> then invokes the real code.
>>
>> Eg:
>>
>>  #!/bin/sh
>>  PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH
>>  export PYTHONPATH
>>  python -m your.module.name ${1+"$@"}
>>
>> Such a script has the advantage that the $PYTHONPATH change applies only to
>> the python running your module, not to your users' wider environment.
>
>This looks doable, though it complicates how I will call my python
>programs.  These are always invoked by the Pinnacle HotScript
>language.  Everything must start from within the Pinnacle planning
>environment.

Well, that makes things easier, potentially. Write a HotScript function to make 
the same arrangement and invoke the Python code. Make all invocations go via 
that function instead of directly.

Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)

From __peter__ at web.de  Tue Aug 29 02:45:56 2017
From: __peter__ at web.de (Peter Otten)
Date: Tue, 29 Aug 2017 08:45:56 +0200
Subject: [Tutor] easygui
References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com>
 <1454183736.1580070.1503799650710@mail.yahoo.com>
 <ontv1q$g1g$1@blaine.gmane.org>
 <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us>
 <1d86903f5382a039651dee6603e8afdd@sonic.net>
Message-ID: <oo32it$ibd$1@blaine.gmane.org>

Alex Kleider wrote:

> On 2017-08-27 07:18, Mats Wichmann wrote:
>> 
>> 
>> or perhaps less intuitively, stick a first line in it to tell the
>> system
>> to have Python run it, so your script looks like this (there are
>> possible variants on that magic first line, but this one should work
>> whichever your platform is, as long as it is the first line):
>> 
>> #!/usr/bin/env python
>> import easygui
>> easygui.msgbox("Hello there")
>> 
>> 
>> and you can then run the script directly.
>> 
> 
> ... After first adjusting permissions:
> 
> $ chmod 755 example,py

The OP already did that. That's why he accidentally ran 'import' rather than 
importing easygui.

$ man import
...
       import - saves any visible window on an X server and outputs it as an 
image file. You can capture a single window, the entire screen, or any 
rectangular portion of the screen.
...

The screenshot will land in a file called easygui.


From kendallevans at hotmail.com.au  Thu Aug 31 02:18:12 2017
From: kendallevans at hotmail.com.au (Kendall Evans)
Date: Thu, 31 Aug 2017 06:18:12 +0000
Subject: [Tutor] Problems Plotting in 3D
Message-ID: <SL2P216MB0841F72A1D5C82FEF6B86928FF9D0@SL2P216MB0841.KORP216.PROD.OUTLOOK.COM>

Hi

I am sorry but I am new to python and am having some problems plotting in 3D spherical coordinates

I am calculating the youngs modulus for a crystal along all directions in space using the method below as I have been given the compliance matrices(C):
                Find S=inv(C)
                Modulus = S(1,1)^-1
                Doing this for a 1 degree interval while sweeping through a 180 degree z axis rotation and a 360 degree x axis rotation

Since I have to do matrix operations I believe I have to iterate across the theta and phi angles. I am wanting to iterate over these to get some radius and then plot this, however my result keeps giving me a blank plot


[cid:image002.png at 01D32274.B90EC520]
[cid:image006.png at 01D32274.B90EC520]
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10


From alan.gauld at yahoo.co.uk  Thu Aug 31 05:01:16 2017
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 31 Aug 2017 10:01:16 +0100
Subject: [Tutor] Problems Plotting in 3D
In-Reply-To: <SL2P216MB0841F72A1D5C82FEF6B86928FF9D0@SL2P216MB0841.KORP216.PROD.OUTLOOK.COM>
References: <SL2P216MB0841F72A1D5C82FEF6B86928FF9D0@SL2P216MB0841.KORP216.PROD.OUTLOOK.COM>
Message-ID: <oo8j8k$c0d$1@blaine.gmane.org>

On 31/08/17 07:18, Kendall Evans wrote:

> I am calculating the youngs modulus for a crystal
>                 Find S=inv(C)
>                 Modulus = S(1,1)^-1

I assume you will be using SciPy for this? There are
dedicated fora for SciPy stuff where you might
find someone who has been down this road before.

https://scipy.org/scipylib/mailing-lists.html

This list is really for the core language and
standard library. However SciPy crops up enough
that you may get an answer here...

>...however my result keeps giving me a blank plot

Show us some code, its very hard to debug something you can't see.
Also are there any error messages? If so post them in full please.

> [cid:image002.png at 01D32274.B90EC520]
> [cid:image006.png at 01D32274.B90EC520]

This is a text only mailing list, if you want to show us an
image you need to post a link. Although, if its truly empty
there's probably not much point! :-)


> Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10

This tells us your OS version. What is your Python version?


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