From d_wobmann at hotmail.com  Tue Jun  2 14:38:36 2020
From: d_wobmann at hotmail.com (Daniel Wobmann)
Date: Tue, 2 Jun 2020 18:38:36 +0000
Subject: [Tutor] Python Networkx with file in gexf format
Message-ID: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com>

Hello everybody,

I'm doing a continuing education, with Python being a relatively large part of it. With my basic knowledge I have practically no chance - especially for the project work, which we have to deliver on June 20, 2020. We are not allowed to use Gephi. Everything must be analyzed and derived in Python. So I am dependent on help and thank you for every support, no matter how small.

I have a dataset in gexf format about the nodes "students" (student-ID) and "teachers" (teacher-ID), where each node belongs to a school class and has a corresponding gender; for teachers no gender is given. There are 10 school classes, e.g. 1A, 2B, etc.
The edges connect the pupil-ID by means of "Origin" and "Destination". The edges are all of the type "Undirected" and weight "1". The "duration" is the duration of all interactions between the nodes (origin and destination); "count" is the number of times the origin and destination have joined together to form an interaction. I have attached the dataset to you.

If someone can help me with this, I would send him/her the dataset by mail. And of course I would pay something for the work.

So far I have managed to get the system to tell me how many nodes and edges there are and what the average degree per node is. That was it.

Now I wish to read out various information from this dataset with Python and the package networkx - and above all to display it graphically. This causes me many difficulties, because in python I want to work with the nodes / edges in the gexf document; but also with the values per item - for example with the value of an ID of a student or with a class name. For this I want to use "networkx". And these are my questions:

1. how can I find out from which data type a feature is? How can I convert the datatype of a feature for example from String to Int (preprocessing engineering)?

2. how can I calculate the number of edges per node (1 origin and how many targets?)? I think this is called "degree", I have seen. What does this code look like? So I want to know how many connections (edges) the node 1551 has to other nodes, for example how many connections the student 1551 has to other students to other students (and teachers). How can I list them per node? What does the code for this look like?
For example, how can I calculate the sum of "counts" or "duration" per student ID? How can I use the result of the number of nodes per Student ID to divide them, for example to calculate the average duration?

4. develop and display the graph for the whole dataset What does the code for this look like?

5. how can I display graphs, i.e. connections and nodes of a single school class (clusters?), single nodes (students) of the same class, etc. with different colors? What does the code for this look like?

6. subgraphs: Are they parts of a whole graph, as I understood it, or? How can I display them for example for between two, three classes, ten students per class, for students and teachers together, etc.? Or for example for the connections within a class? What does the code for this look like?

7. are subgraphs also called "subgroups" and "clusters"? What does the code for this look like so that I can graphically represent such properties? What do I concentrate on in the dataset? For example items? values?

8 How can I determine whether or which student is an "influencer" in the class and which student is not an influencer at all? And which pupil is the "influencer" between school classes? Which are the "inluencers" between school classes? What does the code for this look like?

9. how can I remove items. For example, because they represent an outlier? Or simply remove all those items whose "count" is below 10, for example? What does the code for this look like?

10. weight: I have read a lot about it, but I have not been able to figure out what it is and what purpose it serves. What does this tell me? What can I do with it? How can I change this weight? Why is the weight adjusted in different ways, i.e. for certain connections the weight is often set to 2, for others to 3, etc. And above all: Why should I change a weight, i.e. what could be the intention? What would this mean for "my" dataset? Between all origins and destinations, in our case there is weight 1. Why should I change it? 
Why should it make sense to change weights? In which case would I do this and why? What is the code for changing the weight?

11. How to calculate the following? For example, is this calculated per student or even per cluster (e.g. school class)? Or for which properties is this calculated?
- Degree Centrality
- Betweenness-Zentralit?t)
- Closeness Central Office
- Prestige Indegree
- Ego Network

12. Link Predictions? I heard that there are ways to use different models (or algorithms?) to predict what other possible connections between nodes or the students (in our case) might look like. For example Jaccard, Common Neighbours, Preferential Attachment, Resource Allocation, etc. What does the code for these look like?

I am looking forward to your feedback. Thank you very much and best regards

Daniel Wobmann










From dvsree123 at gmail.com  Tue Jun  2 07:10:56 2020
From: dvsree123 at gmail.com (Divya)
Date: Tue, 2 Jun 2020 16:40:56 +0530
Subject: [Tutor] Practice websites
Message-ID: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>

Please suggest me some websites where I can practice the very basics like
functions, expressions etc..

From alan.gauld at yahoo.co.uk  Tue Jun  2 19:00:05 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 3 Jun 2020 00:00:05 +0100
Subject: [Tutor] Practice websites
In-Reply-To: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>
References: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>
Message-ID: <rb6llm$2sl6$1@ciao.gmane.io>

On 02/06/2020 12:10, Divya wrote:
> Please suggest me some websites where I can practice the very basics like
> functions, expressions etc..


I'm not sure what you are looking for.

There are a couple of web sites with virtual Python interpreters
where you can type basic Python code and it will execute it
for you. If that's what you want here is one I found. I
don't use this service so can't say how good it is but it
seems to handle print("hello") ok...!

https://repl.it/languages/Python3

But most folks find it easier to download Python to their PC
(Or tablet) and use it offline. Especially if you want to process
local data or manipulate you machine in some way.

If on the other hand you are looking for tutorial information there
is a whole page for beginners (one each both non-programmers and
existing programmers in other languages). (Or you can try
mine - see the link in my .sig

Finally, if you want projects or exercises there are some sites
that do that too - I think coursera has some. And the Python
Challenge website is an interesting way to learn new tricks
with Python.

I hope that helps, if not you need to be a bit more specific
about what you are after.

-- 
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  Tue Jun  2 19:12:04 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 2 Jun 2020 18:12:04 -0500
Subject: [Tutor] Named tuple special methods and attributes start with an
 underscore?
Message-ID: <20200602231204.GF23247@Dream-Machine1>

I was reading an article on the collections library
(https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html).
In it it had the following note:  "In Python, methods with leading
underscores are usually considered ?private.? Additional methods provided
by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are
public."  This greatly surprised me.  So I went to the Python docs
(https://docs.python.org/3/library/collections.html#collections.namedtuple)
and found:  "In addition to the methods inherited from tuples, named tuples
support three additional methods and two attributes. To prevent conflicts
with field names, the method and attribute names start with an underscore."
Huh?!?

The mentioned 5 items are:  _make, _asdict, _replace, _fields and
_field_defaults.  Of the items "_replace" is the most surprising as that is
already used by Python in other contexts such as str.replace().  These
items don't look to be likely field names to be used by anyone.  Any
illumination for this design decision?  To my (perhaps naive) eyes this
strikes me as extraordinarily inconsistent Python syntax.

-- 
Wishing you only the best,

boB Stepp

From alan.gauld at yahoo.co.uk  Tue Jun  2 19:27:24 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 3 Jun 2020 00:27:24 +0100
Subject: [Tutor] Python Networkx with file in gexf format
In-Reply-To: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com>
References: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com>
Message-ID: <rb6n8s$2b35$1@ciao.gmane.io>

On 02/06/2020 19:38, Daniel Wobmann wrote:

> I'm doing a continuing education, with Python being a relatively large part of it.

So are you learning python? Or learning something else in which
Python is used? From your message it sounds like the latter?

> We are not allowed to use Gephi. 

Lost me. Never heard of Gephi...

> Everything must be analyzed and derived in Python. 

OK and are they teaching you Python? If not it would seem a tad harsh!

> I have a dataset in gexf format

Nope! never heard of that either.

>  about the nodes "students" (student-ID) and "teachers" (teacher-ID), 
> where each node belongs to a school class and has a corresponding gender;...
> The edges connect the pupil-ID by means of "Origin" and "Destination". 

This all sounds like graph theory. Are you competent in graphs and
the associated math? Or is that part of your course?

> If someone can help me with this, I would send him/her the dataset by mail. 
> And of course I would pay something for the work.

You can of course make any commercial arrangements you wish but
that's not what this list is for. You ask questions about
programming/python/the standard library and we answer them.

> Now I wish to read out various information from this dataset with 
> Python and the package networkx 

Nope, lost me again. Never heard of it.

> - and above all to display it graphically. 

There are several plotting packages in Python. GNUplot is popular.

> This causes me many difficulties, because in python I want to work > with the nodes / edges in the gexf document; but also with the values
per item

It is normal programming practice when dealing with files (of any
format) to read them into memory using a data structure best suited
to the problem. Modified data can be written back to the files (in
the original format) when finished.

Its an exercise in frustration to try to process data in a sub-optimal
data structure intended for data storage rather than manipulation.

> 1. how can I find out from which data type a feature is? How can I 
> convert the datatype of a feature for example from String to Int (preprocessing engineering)?

The usual python approach is to use the int() type conversion.
eg

int("16") returns the number 16.

> 2. how can I calculate the number of edges per node (1 origin and how many targets?)? 

This is more about the choice of algorithm which is a math question not
strictly a Python one. Although the networks package probably has a
predefined algorithm you can use, but you should probably ask their
support forum about that.It is not part of the standard python library.


> 4. develop and display the graph for the whole dataset What does the code for this look like?

It will depend on how you choose to store the data. It may also depend
on what the networkx package offers. Again a question for their forum.

> 5. how can I display graphs, i.e. connections and nodes of a single 
> school class (clusters?), single nodes (students) of the same class, etc. with different colors?> What does the code for this look like?

See 4 above plus the reference to plotting packages...

> 6. subgraphs: Are they parts of a whole graph, as I understood it,

That sounds like a question for your course tutors. Its what
they are there for.

> 7. are subgraphs also called "subgroups" and "clusters"? 

As above.

> 8 How can I determine whether or which student is an "influencer" in the class 

Again this has little to do with python and more to do with
your course theory. I suggest you ask the tutors.

> 9. how can I remove items. For example, because they represent an outlier? 

That will depend on the data structures. Probably a networkx thing again.

> 10. weight: I have read a lot about it, but I have not been able to figure 
> out what it is and what purpose it serves. What does this tell me? What can I do with it? 

Again this is not Python this is your course theory.
Ask your tutors, its their job.

> 11. How to calculate the following? For example, is this calculated per student ...
> - Degree Centrality
> - Betweenness-Zentralit?t)
> - Closeness Central Office
> - Prestige Indegree
> - Ego Network

Again not python. Ask the tutors. Or even your fellow students?

> 12. Link Predictions? I heard that there are ways to use different models (or algorithms?) 
> to predict what other possible connections between nodes or the students (in our case) might 
> look like. For example Jaccard, Common Neighbours, Preferential Attachment, 
> Resource Allocation, etc. What does the code for these look like?

These are all more about the math than python.
The python code will totally depend on the data structures used.
Your networkx package may have some of it pre-coded for you. ask them.

-- 
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 PyTutor at danceswithmice.info  Tue Jun  2 20:31:41 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Wed, 3 Jun 2020 12:31:41 +1200
Subject: [Tutor] Practice websites
In-Reply-To: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>
References: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>
Message-ID: <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info>

On 2/06/20 11:10 PM, Divya wrote:
> Please suggest me some websites where I can practice the very basics like
> functions, expressions etc..


VISUALIZE CODE AND GET LIVE HELP
Learn Python, Java, C, C++, JavaScript, and Ruby
Python Tutor (created by Philip Guo) helps people overcome a fundamental 
barrier to learning programming: understanding what happens as the 
computer runs each line of code.

Write code in your web browser, see it visualized step by step, and get 
live help from volunteers.

Related services: Java Tutor,  C Tutor,  C++ Tutor,  JavaScript Tutor, 
Ruby Tutor

Over ten million people in more than 180 countries have used Python 
Tutor to visualize over 100 million pieces of code, often as a 
supplement to textbooks, lectures, and online tutorials...
http://pythontutor.com/
-- 
Regards =dn

From cs at cskk.id.au  Tue Jun  2 21:23:04 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 3 Jun 2020 11:23:04 +1000
Subject: [Tutor] Named tuple special methods and attributes start with
 an underscore?
In-Reply-To: <20200602231204.GF23247@Dream-Machine1>
References: <20200602231204.GF23247@Dream-Machine1>
Message-ID: <20200603012304.GA52493@cskk.homeip.net>

On 02Jun2020 18:12, boB Stepp <robertvstepp at gmail.com> wrote:
>I was reading an article on the collections library
>(https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html).
>In it it had the following note:  "In Python, methods with leading
>underscores are usually considered ?private.? Additional methods provided
>by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are
>public."  This greatly surprised me.  So I went to the Python docs
>(https://docs.python.org/3/library/collections.html#collections.namedtuple)
>and found:  "In addition to the methods inherited from tuples, named tuples
>support three additional methods and two attributes. To prevent conflicts
>with field names, the method and attribute names start with an underscore."
>Huh?!?
>
>The mentioned 5 items are:  _make, _asdict, _replace, _fields and
>_field_defaults.  Of the items "_replace" is the most surprising as that is
>already used by Python in other contexts such as str.replace().  These
>items don't look to be likely field names to be used by anyone.  Any
>illumination for this design decision?  To my (perhaps naive) eyes this
>strikes me as extraordinarily inconsistent Python syntax.

By using leading underscores, the user of nametuple is free to use any 
field names they like as long as they avoid underscores. Don't forget 
that you can subclass a namedtuple, too. I've got several classes which 
look like this:

    class Something(namedtuple('Something', 'a b c')):
        def some_method(...): ...

You're saying I shouldn't be able to have a method called "replace" on 
my arbitrary class?

The _foo thing is only a convention, through _normally_ strongly adhered 
to. You have the same kind of issue in any shared namespace, and by 
using _foo for a small number of special but documented methods we leave 
the way clear for _any_ starts-with-a-letter name to be a field or 
method of a namedtuple class or subclass.

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

From robertvstepp at gmail.com  Tue Jun  2 22:04:38 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 2 Jun 2020 21:04:38 -0500
Subject: [Tutor] Named tuple special methods and attributes start with
 an underscore?
In-Reply-To: <20200603012304.GA52493@cskk.homeip.net>
References: <20200602231204.GF23247@Dream-Machine1>
 <20200603012304.GA52493@cskk.homeip.net>
Message-ID: <20200603020438.GH23247@Dream-Machine1>

On Wed, Jun 03, 2020 at 11:23:04AM +1000, Cameron Simpson wrote:
>On 02Jun2020 18:12, boB Stepp <robertvstepp at gmail.com> wrote:

>>The mentioned 5 items are:  _make, _asdict, _replace, _fields and
>>_field_defaults.  Of the items "_replace" is the most surprising as that is
>>already used by Python in other contexts such as str.replace().  These
>>items don't look to be likely field names to be used by anyone.  Any
>>illumination for this design decision?  To my (perhaps naive) eyes this
>>strikes me as extraordinarily inconsistent Python syntax.
>
>By using leading underscores, the user of nametuple is free to use any 
>field names they like as long as they avoid underscores. Don't forget 
>that you can subclass a namedtuple, too. I've got several classes 
>which look like this:
>
>   class Something(namedtuple('Something', 'a b c')):
>       def some_method(...): ...
>
>You're saying I shouldn't be able to have a method called "replace" on 
>my arbitrary class?

Then why not str._replace() instead of the current str.replace()?  Is it
thought that users are less likely to want to modify the string class?  Is
this the design criteria -- the likeliness of user subclassing?

-- 
Wishing you only the best,

boB Stepp

From cs at cskk.id.au  Wed Jun  3 01:55:59 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 3 Jun 2020 15:55:59 +1000
Subject: [Tutor] Named tuple special methods and attributes start with
 an underscore?
In-Reply-To: <20200603020438.GH23247@Dream-Machine1>
References: <20200603020438.GH23247@Dream-Machine1>
Message-ID: <20200603055559.GA61937@cskk.homeip.net>

On 02Jun2020 21:04, boB Stepp <robertvstepp at gmail.com> wrote:
>On Wed, Jun 03, 2020 at 11:23:04AM +1000, Cameron Simpson wrote:
>>By using leading underscores, the user of nametuple is free to use any 
>>field names they like as long as they avoid underscores. Don't forget 
>>that you can subclass a namedtuple, too. I've got several classes 
>>which look like this:
>>
>>  class Something(namedtuple('Something', 'a b c')):
>>      def some_method(...): ...
>>
>>You're saying I shouldn't be able to have a method called "replace" 
>>on my arbitrary class?
>
>Then why not str._replace() instead of the current str.replace()?

Because str is a class with many methods and well defined semantics.

namedtuple is essentially an efficient skeleton for a tuple with some 
fixed field names, and initially _no_ semantics/methods. It is basicly a 
bare container. Whereas str is a thing with a purpose.

>Is it
>thought that users are less likely to want to modify the string class?  Is
>this the design criteria -- the likeliness of user subclassing?

It is more that a namedtuple is very basic and has no particular 
behaviours, maybe like object or SimpleNamespace, etc. It goes out of 
its way to _not_ pollute the public space with the (small) number of 
presupplied methods.

There is a rule of thumb that one shouldn't subclass builtin types like 
str, but that is not the criterion here: it is the purpose agnosticness 
of namedtuple.

Let me make a different example. I've got a class which loads CSV or 
Excel sheets and presumes the first row is a heading row. It reads this, 
then constructures a namedtuple subclass whose fields are computed from 
the header names (it does stuff like downcase them and turn whitespace 
into underscores). Anyway, all the field names commence with letters and 
might contain anything depending on the comparative sanity of the person 
supplying the spreadsheet. This is only robust because there are no 
nametuple starts-iwth-a-letter methods.

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

From wescpy at gmail.com  Wed Jun  3 04:08:16 2020
From: wescpy at gmail.com (wesley chun)
Date: Wed, 3 Jun 2020 01:08:16 -0700
Subject: [Tutor] Practice websites
In-Reply-To: <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info>
References: <CAC7eFHTvWYEUTN3=hskVxa+w4gEBRWB8ZCT=hzJUBsOMLJjB_Q@mail.gmail.com>
 <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info>
Message-ID: <CAB6eaA7DvHz6tBEghafQaF89E6CZ+yL2fUEpU2HRgFq1DzpHng@mail.gmail.com>

Hello, this is a very common question and one where you can get many
suggestions with a simple online search. I documented a few in my SO answer
<https://stackoverflow.com/a/3226704/305689> for a similar question.

Cheers,
--Wesley

On Tue, Jun 2, 2020 at 5:32 PM DL Neil via Tutor <tutor at python.org> wrote:

> On 2/06/20 11:10 PM, Divya wrote:
> > Please suggest me some websites where I can practice the very basics like
> > functions, expressions etc..
>
>
> VISUALIZE CODE AND GET LIVE HELP
> Learn Python, Java, C, C++, JavaScript, and Ruby
> Python Tutor (created by Philip Guo) helps people overcome a fundamental
> barrier to learning programming: understanding what happens as the
> computer runs each line of code.
>
> Write code in your web browser, see it visualized step by step, and get
> live help from volunteers.
>
> Related services: Java Tutor,  C Tutor,  C++ Tutor,  JavaScript Tutor,
> Ruby Tutor
>
> Over ten million people in more than 180 countries have used Python
> Tutor to visualize over 100 million pieces of code, often as a
> supplement to textbooks, lectures, and online tutorials...
> http://pythontutor.com/
> --
> Regards =dn


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"A computer never does what you want... only what you tell it."
    +wesley chun : wescpy at gmail : @wescpy
    Python training & consulting : http://CyberwebConsulting.com
    "Core Python" books : http://CorePython.com
    Python blog: http://wescpy.blogspot.com

From mats at wichmann.us  Wed Jun  3 14:17:10 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Wed, 3 Jun 2020 12:17:10 -0600
Subject: [Tutor] Python Networkx with file in gexf format
In-Reply-To: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com>
References: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com>
Message-ID: <9b2a0480-2a0b-490e-ca58-c22154a4cb3e@wichmann.us>

On 6/2/20 12:38 PM, Daniel Wobmann wrote:
> Hello everybody,
> 
> I'm doing a continuing education, with Python being a relatively large part of it. With my basic knowledge I have practically no chance - especially for the project work, which we have to deliver on June 20, 2020. We are not allowed to use Gephi. Everything must be analyzed and derived in Python. So I am dependent on help and thank you for every support, no matter how small.
> 
> I have a dataset in gexf format 

...

> Now I wish to read out various information from this dataset with Python and the package networkx 
as Alan has pointed out, this is pretty sophisticated stuff.

NetworkX is a currently popular package for dealing with network graphs,
and it's able to deal in both the older gexf format and the newer
graphml format.  So all the boxes are ticked.  But if you're getting all
of this thrown at you at once, that's a big load to swallow.

I'm about to delve in a little bit, because of an incoming request on a
project I work on, but that door hasn't been opened yet for me.

You're unlikely to get much help here, unless one of the contributors
happens to be a practitioner; there are thousands upon thousands of
Python packages, nobody knows them all.

I'd suggest digging around a bit on the NetworkX mailing list, which is
a Google Group and thus pretty easily searchable, to see if there are
people you can talk to.

https://groups.google.com/forum/#!forum/networkx-discuss


From robertvstepp at gmail.com  Wed Jun  3 23:36:30 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 3 Jun 2020 22:36:30 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <20200531014208.GA23247@Dream-Machine1>
References: <20200531014208.GA23247@Dream-Machine1>
Message-ID: <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>

I have been continuing to try to understand what is going on.

On Sat, May 30, 2020 at 8:42 PM boB Stepp <robertvstepp at gmail.com> wrote:
>
> The following function yields type annotation errors and I do not
> understand why:
>
> def evaluate_portfolio(
>      portfolio: List[Dict[str, Union[str, int, float]]], stock_prices: Dict[str, float]
> ) -> Tuple[float, float]:
>      """Compute the current value and gain/loss of a portfolio."""
>      portfolio_value = 0.0
>      gain_loss = 0.0
>      for stock in portfolio:
>          current_value = stock["shares"] * stock_prices[stock["name"]]
>          current_gain_loss = current_value - (stock["shares"] * stock["price"])
>          portfolio_value += current_value
>          gain_loss += current_gain_loss
>      return portfolio_value, gain_loss
>
> The error messages generated are:
>
> report.py|47 col 43 info| Left operand is of type "Union[str, int, float]"
> report.py|47 col 43 error| Unsupported operand types for * ("str" and "float")
> report.py|47 col 56 error| Invalid index type "Union[str, int, float]" for "Dict[str, float]"; expected type "str"
> report.py|48 col 29 info| Both left and right operands are unions
> report.py|48 col 29 error| Unsupported operand types for - ("float" and "str")
> report.py|48 col 46 error| Unsupported operand types for * ("str" and "str")
> report.py|48 col 46 error| Unsupported operand types for * ("str" and "float")
> report.py|48 col 46 error| Unsupported operand types for * ("float" and "str")

If I simplify the type annotations to:

def evaluate_portfolio(
    portfolio: List[Dict], stock_prices: Dict[str, float]
) -> Tuple[float, float]:
    """Compute the current value and gain/loss of a portfolio."""
    portfolio_value = 0.0
    gain_loss = 0.0
    for stock in portfolio:
        current_value = stock["shares"] * stock_prices[stock["name"]]
        current_gain_loss = current_value - (stock["shares"] * stock["price"])
        portfolio_value += current_value
        gain_loss += current_gain_loss
    return portfolio_value, gain_loss

Then all of the complaints go away.  I still do not understand why the
more detailed annotations do not give the expected results.  I have
read and reread the documentation multiple times, but I believe I am
doing the annotations correctly.  Perhaps there is a nesting limit
beyond which mypy chokes?

-- 
boB

From robertvstepp at gmail.com  Thu Jun  4 00:30:51 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 3 Jun 2020 23:30:51 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
Message-ID: <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>

As I continue to integrate type annotations with David Beazley's
recently released course, "Practical Python Programming", I ran into
another issue.  I have pared down a larger function to just what seems
to be giving the type annotation complaint:

def parse_csv(data_rows: List, has_headers: bool = True) -> List:
    """Parse a CSV file into a list of records."""
    data_rows_iter = iter(data_rows)
    if has_headers:
        headers = next(data_rows_iter)
    records = []
    for row in data_rows_iter:
        if has_headers:
            # Make a dictionary
            record = dict(zip(headers, row))
        else:
            # Otherwise make a tuple
            record = tuple(row)
    records.append(record)

    return records

The complaint is:  test.py|19 col 22 error| Incompatible types in
assignment (expression has type "Tuple[Any, ...]", variable has type
"Dict[Any, Any]")

One of the exercises is to return a list of dictionaries if a csv file
has headers, but if not to return a list of tuples.  mypy apparently
does not like this.  In the "Type hints cheat sheet..." (at
https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) in the
section "When you're puzzled or when things are complicated" it
discusses the use of "Any":

"Use Any if you don't know the type of something or it's too dynamic
to write a type for..."

This does not seem particularly complicated to me, so I'm probably
doing something bad or screwy.  Any thoughts?

BTW, the above function works.  If I run it with:

with_headers = [["a", "b", "c"], [1, 2, 3]]
without_headers = [[1, 2, 3]]

my_dict = parse_csv(with_headers)
my_tuple = parse_csv(without_headers, has_headers=False)

print("My dict =", my_dict)
print()
print("My tuple =", my_tuple)

I get my expected result:

bob at Dream-Machine1:~/practical-python/Work$ python3 test.py
My dict = [{'a': 1, 'b': 2, 'c': 3}]

My tuple = [(1, 2, 3)]

-- 
boB

From __peter__ at web.de  Thu Jun  4 04:10:41 2020
From: __peter__ at web.de (Peter Otten)
Date: Thu, 04 Jun 2020 10:10:41 +0200
Subject: [Tutor] Type annotation errors
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
 <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
Message-ID: <rbaaa2$3g48$1@ciao.gmane.io>

boB Stepp wrote:

> As I continue to integrate type annotations with David Beazley's
> recently released course, "Practical Python Programming", I ran into
> another issue.  I have pared down a larger function to just what seems
> to be giving the type annotation complaint:
> 
> def parse_csv(data_rows: List, has_headers: bool = True) -> List:
>     """Parse a CSV file into a list of records."""
>     data_rows_iter = iter(data_rows)
>     if has_headers:
>         headers = next(data_rows_iter)
>     records = []
>     for row in data_rows_iter:
>         if has_headers:
>             # Make a dictionary
>             record = dict(zip(headers, row))
>         else:
>             # Otherwise make a tuple
>             record = tuple(row)
>     records.append(record)
> 
>     return records
> 
> The complaint is:  test.py|19 col 22 error| Incompatible types in
> assignment (expression has type "Tuple[Any, ...]", variable has type
> "Dict[Any, Any]")
> 
> One of the exercises is to return a list of dictionaries if a csv file
> has headers, but if not to return a list of tuples.  mypy apparently
> does not like this.  In the "Type hints cheat sheet..." (at
> https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) in the
> section "When you're puzzled or when things are complicated" it
> discusses the use of "Any":
> 
> "Use Any if you don't know the type of something or it's too dynamic
> to write a type for..."
> 
> This does not seem particularly complicated to me, so I'm probably
> doing something bad or screwy. Any thoughts?

Let me note that I do not have any experience with mypy.
However, the following

>         if has_headers:
>             # Make a dictionary
>             record = dict(zip(headers, row))
>         else:
>             # Otherwise make a tuple
>             record = tuple(row)

makes every user of classical statically typed languages cringe.
What's the type of record after the above? It's either the type of

dict(zip(headers, row))

or the type of

tuple(row)

I don't know if mypy is not smart enough or just refuses to infer the type 
-- in any case you can help it with a declaration.
The most generic would be

record: Any

but making a union from the types in the error message should work too.

record: Union[Tuple[Any, ...], Dict[Any, Any]]

You might try to tighten that a bit -- e. g. requiring the dict keys to be 
strings. 

There are other things that you may know about the types 

- all records of one function run will be either tuples or dicts, never a
  mixture
- all iterables in the data_rows list should have the same "length"
- the first item in the data_rows list should be an iterable of strings if
  has_headers is true

where I have no idea how it might be explained to a type checker. I fear 
that a moderately clean typed soluton would require two separate functions

parse_csv()
parse_csv_with_headers()

> BTW, the above function works.

Hooray to Python's ducktyping ;)

> If I run it with:
> 
> with_headers = [["a", "b", "c"], [1, 2, 3]]
> without_headers = [[1, 2, 3]]
> 
> my_dict = parse_csv(with_headers)
> my_tuple = parse_csv(without_headers, has_headers=False)
> 
> print("My dict =", my_dict)
> print()
> print("My tuple =", my_tuple)
> 
> I get my expected result:
> 
> bob at Dream-Machine1:~/practical-python/Work$ python3 test.py
> My dict = [{'a': 1, 'b': 2, 'c': 3}]
> 
> My tuple = [(1, 2, 3)]
> 



From __peter__ at web.de  Thu Jun  4 09:46:51 2020
From: __peter__ at web.de (Peter Otten)
Date: Thu, 04 Jun 2020 15:46:51 +0200
Subject: [Tutor] Type annotation errors
References: <20200531014208.GA23247@Dream-Machine1>
Message-ID: <rbau1g$klb$1@ciao.gmane.io>

boB Stepp wrote:

One more (remember I'm very new to mypy):

> The following function yields type annotation errors and I do not
> understand why:
> 
> def evaluate_portfolio(
>      portfolio: List[Dict[str, Union[str, int, float]]], stock_prices:
>      Dict[str, float]
> ) -> Tuple[float, float]:
>      """Compute the current value and gain/loss of a portfolio."""
>      portfolio_value = 0.0
>      gain_loss = 0.0
>      for stock in portfolio:
>          current_value = stock["shares"] * stock_prices[stock["name"]]
>          current_gain_loss = current_value - (stock["shares"] *
>          stock["price"]) portfolio_value += current_value
>          gain_loss += current_gain_loss
>      return portfolio_value, gain_loss
> 
> The error messages generated are:
> 
> report.py|47 col 43 info| Left operand is of type "Union[str, int, float]"
> report.py|47 col 43 error| Unsupported operand types for * ("str" and
> "float") 

Given 

x: Union[str, int, float] 
y: float
x * y

mypy ensures that * is defined for

str * float  # error
int * float  # OK
float * float  # OK

There might be a way to tell mypy that two cases cannot occur and still use 
dicts as pseudo-structs, but I expect that there will be a big impact of 
optional typing on the design, and unlike unit tests it will not just 
improve the structure, it will also make the code less flexible.
Replacing the somewhat amorphous dict with a dataclass:

Money = float  # fixme

@dataclass
class Record:
    shares: int
    name: str
    price: Money


def evaluate_portfolio(
        portfolio: List[Record],
        stock_prices: Dict[str, Money]
) -> Tuple[float, float]:
     """Compute the current value and gain/loss of a portfolio."""
     portfolio_value = 0.0
     gain_loss = 0.0
     for stock in portfolio:
         current_value = stock.shares * stock_prices[stock.name]
         current_gain_loss = current_value - stock.shares * stock.price
         portfolio_value += current_value
         gain_loss += current_gain_loss
     return portfolio_value, gain_loss

PS: In spite of my defeatist remark above I prefer this version over the one 
you posted; maybe not all is lost in Python land ;)

PPS: For someone who knows a little C the obvious fix for your version is to 
cast the union to the expected type:

    for stock in portfolio:
         shares = cast(int, stock["shares"])
         name = cast(str, stock["name"])
         price = cast(float, stock["price"])

         current_value =  shares * stock_prices[name]
         current_gain_loss = current_value - shares * price
         portfolio_value += current_value
         gain_loss += current_gain_loss


> report.py|47 col 56 error| Invalid index type "Union[str, int,
> float]" for "Dict[str, float]"; expected type "str" report.py|48 col 29
> info| Both left and right operands are unions report.py|48 col 29 error|
> Unsupported operand types for - ("float" and "str") report.py|48 col 46
> error| Unsupported operand types for * ("str" and "str") report.py|48 col
> 46 error| Unsupported operand types for * ("str" and "float") report.py|48
> col 46 error| Unsupported operand types for * ("float" and "str")
> 
> For reference line 47 is the line in the for loop beginning
> "current_value..."
> 
> portfolio is a list of dictionaries where each dictionary is of the form
> {"name": "stock name", "shares": number_of_shares_owned, "price":
> price_per_share}
> 
> The code runs flawlessly and gives the expected results.  Where am I going
> wrong in my type annotations?
> 



From __peter__ at web.de  Thu Jun  4 10:31:24 2020
From: __peter__ at web.de (Peter Otten)
Date: Thu, 04 Jun 2020 16:31:24 +0200
Subject: [Tutor] Type annotation errors
References: <20200531014208.GA23247@Dream-Machine1>
 <rbau1g$klb$1@ciao.gmane.io>
Message-ID: <rbb0k7$2o88$1@ciao.gmane.io>

Peter Otten wrote:

> There might be a way to tell mypy that two cases cannot occur and still
> use dicts as pseudo-structs

I found

https://mypy.readthedocs.io/en/stable/more_types.html#typeddict

with that:

from typing_extensions import TypedDict

Record = TypedDict("Record", {"shares": int, "name": str, "price": float})

def evaluate_portfolio(
          portfolio: List[Record], stock_prices: Dict[str, float]
) -> Tuple[float, float]:
    ... # body unchanged


From mats at wichmann.us  Thu Jun  4 11:32:39 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 4 Jun 2020 09:32:39 -0600
Subject: [Tutor] Type annotation errors
In-Reply-To: <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
 <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
Message-ID: <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us>

On 6/3/20 10:30 PM, boB Stepp wrote:
> As I continue to integrate type annotations with David Beazley's
> recently released course, "Practical Python Programming", I ran into
> another issue.  I have pared down a larger function to just what seems
> to be giving the type annotation complaint:
> 
> def parse_csv(data_rows: List, has_headers: bool = True) -> List:
>     """Parse a CSV file into a list of records."""
>     data_rows_iter = iter(data_rows)
>     if has_headers:
>         headers = next(data_rows_iter)
>     records = []
>     for row in data_rows_iter:
>         if has_headers:
>             # Make a dictionary
>             record = dict(zip(headers, row))
>         else:
>             # Otherwise make a tuple
>             record = tuple(row)
>     records.append(record)
> 
>     return records
> 
> The complaint is:  test.py|19 col 22 error| Incompatible types in
> assignment (expression has type "Tuple[Any, ...]", variable has type
> "Dict[Any, Any]")
> 
> One of the exercises is to return a list of dictionaries if a csv file
> has headers, but if not to return a list of tuples.  mypy apparently
> does not like this. 

I don't like it either :)   (I know, who am I to criticize dabeaz - even
if I did so professionally for a very short period as one of his
technical editors on Python Essential Reference 2:e way back in 2000).

Functions/methods that return different types under different calling
scenarios  are certainly possible in Python, but that doesn't mean it's
a great idea for usability.  A contrived learning example is fine; In
Real Life, I don't see why on earth you'd want this awkward setup. So
worrying too much about twisting typing so mypy is happy about this
doesn't seem terribly worthwhile... just sayin'.



From robertvstepp at gmail.com  Thu Jun  4 14:01:42 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 4 Jun 2020 13:01:42 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <rbaaa2$3g48$1@ciao.gmane.io>
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
 <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
 <rbaaa2$3g48$1@ciao.gmane.io>
Message-ID: <20200604180142.GI23247@Dream-Machine1>

Ah, Peter, you gave me the pieces I needed to put it all together (I
think.).

On Thu, Jun 04, 2020 at 10:10:41AM +0200, Peter Otten wrote:
>boB Stepp wrote:
>
>> ...I have pared down a larger function to just what seems
>> to be giving the type annotation complaint:
>>
>> def parse_csv(data_rows: List, has_headers: bool = True) -> List:
>>     """Parse a CSV file into a list of records."""
>>     data_rows_iter = iter(data_rows)
>>     if has_headers:
>>         headers = next(data_rows_iter)
>>     records = []
>>     for row in data_rows_iter:
>>         if has_headers:
>>             # Make a dictionary
>>             record = dict(zip(headers, row))
>>         else:
>>             # Otherwise make a tuple
>>             record = tuple(row)
>>     records.append(record)
>>
>>     return records
>>
>> The complaint is:  test.py|19 col 22 error| Incompatible types in
>> assignment (expression has type "Tuple[Any, ...]", variable has type
>> "Dict[Any, Any]")

>Let me note that I do not have any experience with mypy.
>However, the following
>
>>         if has_headers:
>>             # Make a dictionary
>>             record = dict(zip(headers, row))
>>         else:
>>             # Otherwise make a tuple
>>             record = tuple(row)
>
>makes every user of classical statically typed languages cringe.
>What's the type of record after the above? It's either the type of
>
>dict(zip(headers, row))
>
>or the type of
>
>tuple(row)
>
>I don't know if mypy is not smart enough or just refuses to infer the type
>-- in any case you can help it with a declaration.
>The most generic would be
>
>record: Any
>
>but making a union from the types in the error message should work too.
>
>record: Union[Tuple[Any, ...], Dict[Any, Any]]

This is the key bit that made it all come together for me.  I had annotated
the function's parameters and its return types, but did not try to "help"
mypy with declaring one of the intermediate identifiers.  And you caused me
to remember that I am allowed to declare types of identifiers without
assignment.  I added the following just after my function's docstring and
it resolved the issue:

record: Union[Tuple[Any, ...], Dict[str, Any]]

>There are other things that you may know about the types
>
>- all records of one function run will be either tuples or dicts, never a
>  mixture
>- all iterables in the data_rows list should have the same "length"
>- the first item in the data_rows list should be an iterable of strings if
>  has_headers is true
>
>where I have no idea how it might be explained to a type checker. I fear
>that a moderately clean typed soluton would require two separate functions
>
>parse_csv()
>parse_csv_with_headers()

The points you list above are ones I have already given some thought to,
wondering if I should build in some checks.  But as the "real problem" I am
working with is part of a series of exercises I am waiting to see where
Beasley is taking this.  So far he has been using an incremental approach
"improving" the ever growing and morphing program(s) as he introduces more
Python.

Beasley mentioned type annotations very briefly, but I have been applying
them throughout the course as that is one of my current points of learning
that I have set for myself.

>> BTW, the above function works.
>
>Hooray to Python's ducktyping ;)

Amen!

-- 
Wishing you only the best,

boB Stepp

From robertvstepp at gmail.com  Thu Jun  4 14:14:45 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 4 Jun 2020 13:14:45 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us>
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
 <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
 <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us>
Message-ID: <20200604181445.GJ23247@Dream-Machine1>

On Thu, Jun 04, 2020 at 09:32:39AM -0600, Mats Wichmann wrote:
>On 6/3/20 10:30 PM, boB Stepp wrote:

>> One of the exercises is to return a list of dictionaries if a csv file
>> has headers, but if not to return a list of tuples.  mypy apparently
>> does not like this.
>
>I don't like it either :)   (I know, who am I to criticize dabeaz - even
>if I did so professionally for a very short period as one of his
>technical editors on Python Essential Reference 2:e way back in 2000).

The actual set of exercises is from "3.2 Moe on Functions" at
https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/02_More_functions.html

In this exercise set he wishes to create a module fileparse which can
accept a csv-like file and allow one to obtain a list of dictionaries (one
per file row) if the file has headers or a list of tuples if not,
representing the collection of records.  Additionally he wishes to allow
for setting arguments to choose only certain data columns (If the file has
headers), do type conversions by providing a list of functions to do the
conversions, and setting a different delimiter than the default comma.  At
the end of the exercises he comments:

"If you?ve made it this far, you?ve created a nice library function that?s
genuinely useful. You can use it to parse arbitrary CSV files, select out
columns of interest, perform type conversions, without having to worry too
much about the inner workings of files or the csv module."

>Functions/methods that return different types under different calling
>scenarios  are certainly possible in Python, but that doesn't mean it's
>a great idea for usability.  A contrived learning example is fine; In
>Real Life, I don't see why on earth you'd want this awkward setup. So
>worrying too much about twisting typing so mypy is happy about this
>doesn't seem terribly worthwhile... just sayin'.

However, I have to say, the end result *does* seem useful!

-- 
Wishing you only the best,

boB Stepp

From alan.gauld at yahoo.co.uk  Thu Jun  4 19:07:55 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 5 Jun 2020 00:07:55 +0100
Subject: [Tutor] Type annotation errors
In-Reply-To: <20200604181445.GJ23247@Dream-Machine1>
References: <20200531014208.GA23247@Dream-Machine1>
 <CANDiX9Jc6uPi3YjNXJenVmg8frcnQcL6tY-YwTY4Uutej-k+cQ@mail.gmail.com>
 <CANDiX9LHH+pGPecJj-BLNw-AFM_Kop7z9EWn6QOr8+EKN++-AA@mail.gmail.com>
 <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us>
 <20200604181445.GJ23247@Dream-Machine1>
Message-ID: <rbbusb$3lk8$1@ciao.gmane.io>

On 04/06/2020 19:14, boB Stepp wrote:

> In this exercise set he wishes to create a module fileparse which can
> accept a csv-like file and allow one to obtain a list of dictionaries (one
> per file row) if the file has headers or a list of tuples if not,
> representing the collection of records.

But is that really useful? If you don;t know if the file has headers or
not you have to examine the type of the result to find out.
If you do know in advance you can just have two separate functions. And
if you don't know if it has headers why not create a function that
examines the file before parsing so you can write

if hasHeaders(file):
    parseHeaderFile(file)
else:
    parseNoHeaders(file)

Then you know what type of result you get. Better to check the
state of the data than try to derive types afterwards.

Functions that  try to handle two different types of input by
returning two different types of output are really just two
functions bound in one. (Different if you can return a
single data type for two inputs)

I don't know the book so maybe he is heading towards a single
unified object model with polymorphic methods so that you
can treat the two results as a single ParseResult object.
It is certainly possible to create a polymorphic solution,
but it is a lot of work.

But otherwise I'd say it's a bad design that inevitably leads
to maintenance headaches.


>   Additionally he wishes to allow
> for setting arguments to choose only certain data columns (If the file has
> headers), do type conversions by providing a list of functions to do the
> conversions, and setting a different delimiter than the default comma.  At
> the end of the exercises he comments:
> 
> "If you?ve made it this far, you?ve created a nice library function that?s
> genuinely useful. You can use it to parse arbitrary CSV files, select out
> columns of interest, perform type conversions, without having to worry too
> much about the inner workings of files or the csv module."

Sorry, but it sounds like it should be a library of functions.
That is one function overloaded way too far. Maintaining it
will be a nightmare. Imagine the number of regression tests
required for even a minor change! I know we can automate them
but it's still a sign of a design anti-pattern.

-- 
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 Jun  4 20:34:36 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 4 Jun 2020 19:34:36 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <rbau1g$klb$1@ciao.gmane.io>
References: <20200531014208.GA23247@Dream-Machine1>
 <rbau1g$klb$1@ciao.gmane.io>
Message-ID: <20200605003436.GK23247@Dream-Machine1>

On Thu, Jun 04, 2020 at 03:46:51PM +0200, Peter Otten wrote:
>boB Stepp wrote:

>There might be a way to tell mypy that two cases cannot occur and still use
>dicts as pseudo-structs, but I expect that there will be a big impact of
>optional typing on the design, and unlike unit tests it will not just
>improve the structure, it will also make the code less flexible.
>Replacing the somewhat amorphous dict with a dataclass:
>
>Money = float  # fixme
>
>@dataclass
>class Record:
>    shares: int
>    name: str
>    price: Money
>
>
>def evaluate_portfolio(
>        portfolio: List[Record],
>        stock_prices: Dict[str, Money]
>) -> Tuple[float, float]:
>     """Compute the current value and gain/loss of a portfolio."""
>     portfolio_value = 0.0
>     gain_loss = 0.0
>     for stock in portfolio:
>         current_value = stock.shares * stock_prices[stock.name]
>         current_gain_loss = current_value - stock.shares * stock.price
>         portfolio_value += current_value
>         gain_loss += current_gain_loss
>     return portfolio_value, gain_loss
>
>PS: In spite of my defeatist remark above I prefer this version over the one
>you posted; maybe not all is lost in Python land ;)

In terms of following along with Beazley's course material this would be
cheating.  Classes have not been presented yet.  Even very simple ones.
~(:>))

>PPS: For someone who knows a little C the obvious fix for your version is to
>cast the union to the expected type:
>
>    for stock in portfolio:
>         shares = cast(int, stock["shares"])
>         name = cast(str, stock["name"])
>         price = cast(float, stock["price"])
>
>         current_value =  shares * stock_prices[name]
>         current_gain_loss = current_value - shares * price
>         portfolio_value += current_value
>         gain_loss += current_gain_loss

I saw cast() in the mypy documentation, but had hopes that the problem was
me and my lack of understanding.

-- 
Wishing you only the best,

boB Stepp

From robertvstepp at gmail.com  Thu Jun  4 20:41:52 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 4 Jun 2020 19:41:52 -0500
Subject: [Tutor] Type annotation errors
In-Reply-To: <rbb0k7$2o88$1@ciao.gmane.io>
References: <20200531014208.GA23247@Dream-Machine1>
 <rbau1g$klb$1@ciao.gmane.io> <rbb0k7$2o88$1@ciao.gmane.io>
Message-ID: <20200605004152.GL23247@Dream-Machine1>

On Thu, Jun 04, 2020 at 04:31:24PM +0200, Peter Otten wrote:
>Peter Otten wrote:
>
>> There might be a way to tell mypy that two cases cannot occur and still
>> use dicts as pseudo-structs
>
>I found
>
>https://mypy.readthedocs.io/en/stable/more_types.html#typeddict
>
>with that:
>
>from typing_extensions import TypedDict
>
>Record = TypedDict("Record", {"shares": int, "name": str, "price": float})
>
>def evaluate_portfolio(
>          portfolio: List[Record], stock_prices: Dict[str, float]
>) -> Tuple[float, float]:
>    ... # body unchanged

Hmm.  This seems to be the exactly what the situation requires.  I had not
looked into typing_extensions yet.  Thanks!

-- 
Wishing you only the best,

boB Stepp

From PyTutor at danceswithmice.info  Fri Jun  5 05:13:40 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Fri, 5 Jun 2020 21:13:40 +1200
Subject: [Tutor] Type annotation errors
In-Reply-To: <20200605003436.GK23247@Dream-Machine1>
References: <20200531014208.GA23247@Dream-Machine1>
 <rbau1g$klb$1@ciao.gmane.io> <20200605003436.GK23247@Dream-Machine1>
Message-ID: <55169a4d-28e6-07d9-bafc-6d870647ad50@DancesWithMice.info>

> In terms of following along with Beazley's course material this would be
> cheating.? Classes have not been presented yet.? Even very simple ones.
> ~(:>))
> 
>> PPS: For someone who knows a little C the obvious fix for your version 
>> is to
>> cast the union to the expected type:


This is a little difficult to rationalise:
- we are not trying to get ahead of the course material
- but we are prepared to launch into complex (if not complicated) mypy
Apologies, I can see the 'why' but can't help but feel it is only that 
imbalance which has led to the problem...


I'd like to discuss the (actual) problem, and then dispute the 
claim-pursuant:

[from another part of the thread]
<<<
In this exercise set he wishes to create a module fileparse which can
accept a csv-like file and allow one to obtain a list of dictionaries (one
per file row) if the file has headers or a list of tuples if not,
representing the collection of records.  Additionally he wishes to allow
for setting arguments to choose only certain data columns (If the file has
headers), do type conversions by providing a list of functions to do the
conversions, and setting a different delimiter than the default comma.  At
the end of the exercises he comments:

"If you?ve made it this far, you?ve created a nice library function that?s
genuinely useful. You can use it to parse arbitrary CSV files, select out
columns of interest, perform type conversions, without having to worry too
much about the inner workings of files or the csv module."
 >>>

I'm firmly joining with others who have suggested that rather than 
"nice" it is actually quite 'ugly'. The routine, as-is, violates the 
Single Responsibility Principle (SRP). It is trying to deal with CSV 
files that have column headings AND those which don't. That's not an 
horrendous crime, per-se (but see later). However, the idea that the 
routine will output either a list of dicts or a list of tuples, most 
certainly is a major transgression!

The Zen of Python says "Simple is better than complex. Complex is better 
than complicated.". Which of the three describes that code?

To be fair, you weren't intending to discuss the course 
materials/output, and IIRC there has been no explanation as to how the 
calling routine 'knows' whether this .CSV has headers or not. Similarly, 
it does not say how it will deal with the two-format output issue when 
it comes time to actually use the extracted-data.

Regarding the first, wouldn't it make sense to not only ascertain that 
headers are present (or not) AND note any headings - as a single task?

Now, instead of varying the function's output according to the presence 
of headers (or not), the data could be extracted (only) as a tuple.

Lastly, when it comes time to further-process the extracted-data, it can 
be paired/zipped with the headings, if-possible, as-required...

Alternately, write the basic function (no headings) and then add a 
decorator to handle headings - separation in a different fashion.

To those, apply the Zen?

Now apply mypy to the function (even design-level stubs)?


Per the comment "nice library function", I'm hoping that you will later 
report that the course builds-upon this/these function(s) and makes them 
even more useful/"nice". Speaking for myself, and because I have 
frequent needs to extract data from worksheets or .CSV files, I have a 
bunch of classes ready for re-use (sub-classing per file/application) 
and find them *very* useful.

As a general rule, I find that the greatest re-use is of simple classes 
rather than those more complex or complicated. The complexity comes when 
the simple 'framework' of a base-class is adapted and expanded to suit 
the application. So, SRP rules!


It might be a little early to throw at you what is possibly the hardest 
part of "SOLID" to understand and implement by-habit (but I know you've 
used multiple languages over the years, before tackling Python): the 
Dependency Inversion Principle (DIP) wherein we say that "details should 
depend on abstractions" not "abstractions depend upon details".

In this mode, we abstract the process of taking data from a worksheet. 
Then, isn't the absence/presence of headings, a 'detail'?

(just as another hint for the course's future: that we might only wish 
to extract specific columns ("select") or rows ("project")...) Each of 
these 'details' refines the extraction process rather than calls for an 
entirely different method of extraction/different presentation of the 
results!
-- 
Regards =dn

From nihal.shiva007 at gmail.com  Fri Jun  5 02:39:37 2020
From: nihal.shiva007 at gmail.com (Nihal shivakumar)
Date: Fri, 5 Jun 2020 12:09:37 +0530
Subject: [Tutor] Tutor Digest, Vol 196, Issue 1
In-Reply-To: <mailman.671.1591139529.24730.tutor@python.org>
References: <mailman.671.1591139529.24730.tutor@python.org>
Message-ID: <CANRF5jx8snA-vJ3TF-FRAwVEW_JzRsEc4cQ6mQ7kECqPBMyRCg@mail.gmail.com>

Use website coursera
Make account and learn audit the courses
Learn from many university and google as well

On Wed 3 Jun, 2020, 4:42 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. Python Networkx with file in gexf format (Daniel Wobmann)
>    2. Practice websites (Divya)
>    3. Re: Practice websites (Alan Gauld)
>    4. Named tuple special methods and attributes start with an
>       underscore? (boB Stepp)
>
>
>
> ---------- Forwarded message ----------
> From: Daniel Wobmann <d_wobmann at hotmail.com>
> To: "tutor at python.org" <tutor at python.org>
> Cc:
> Bcc:
> Date: Tue, 2 Jun 2020 18:38:36 +0000
> Subject: [Tutor] Python Networkx with file in gexf format
> Hello everybody,
>
> I'm doing a continuing education, with Python being a relatively large
> part of it. With my basic knowledge I have practically no chance -
> especially for the project work, which we have to deliver on June 20, 2020.
> We are not allowed to use Gephi. Everything must be analyzed and derived in
> Python. So I am dependent on help and thank you for every support, no
> matter how small.
>
> I have a dataset in gexf format about the nodes "students" (student-ID)
> and "teachers" (teacher-ID), where each node belongs to a school class and
> has a corresponding gender; for teachers no gender is given. There are 10
> school classes, e.g. 1A, 2B, etc.
> The edges connect the pupil-ID by means of "Origin" and "Destination". The
> edges are all of the type "Undirected" and weight "1". The "duration" is
> the duration of all interactions between the nodes (origin and
> destination); "count" is the number of times the origin and destination
> have joined together to form an interaction. I have attached the dataset to
> you.
>
> If someone can help me with this, I would send him/her the dataset by
> mail. And of course I would pay something for the work.
>
> So far I have managed to get the system to tell me how many nodes and
> edges there are and what the average degree per node is. That was it.
>
> Now I wish to read out various information from this dataset with Python
> and the package networkx - and above all to display it graphically. This
> causes me many difficulties, because in python I want to work with the
> nodes / edges in the gexf document; but also with the values per item - for
> example with the value of an ID of a student or with a class name. For this
> I want to use "networkx". And these are my questions:
>
> 1. how can I find out from which data type a feature is? How can I convert
> the datatype of a feature for example from String to Int (preprocessing
> engineering)?
>
> 2. how can I calculate the number of edges per node (1 origin and how many
> targets?)? I think this is called "degree", I have seen. What does this
> code look like? So I want to know how many connections (edges) the node
> 1551 has to other nodes, for example how many connections the student 1551
> has to other students to other students (and teachers). How can I list them
> per node? What does the code for this look like?
> For example, how can I calculate the sum of "counts" or "duration" per
> student ID? How can I use the result of the number of nodes per Student ID
> to divide them, for example to calculate the average duration?
>
> 4. develop and display the graph for the whole dataset What does the code
> for this look like?
>
> 5. how can I display graphs, i.e. connections and nodes of a single school
> class (clusters?), single nodes (students) of the same class, etc. with
> different colors? What does the code for this look like?
>
> 6. subgraphs: Are they parts of a whole graph, as I understood it, or? How
> can I display them for example for between two, three classes, ten students
> per class, for students and teachers together, etc.? Or for example for the
> connections within a class? What does the code for this look like?
>
> 7. are subgraphs also called "subgroups" and "clusters"? What does the
> code for this look like so that I can graphically represent such
> properties? What do I concentrate on in the dataset? For example items?
> values?
>
> 8 How can I determine whether or which student is an "influencer" in the
> class and which student is not an influencer at all? And which pupil is the
> "influencer" between school classes? Which are the "inluencers" between
> school classes? What does the code for this look like?
>
> 9. how can I remove items. For example, because they represent an outlier?
> Or simply remove all those items whose "count" is below 10, for example?
> What does the code for this look like?
>
> 10. weight: I have read a lot about it, but I have not been able to figure
> out what it is and what purpose it serves. What does this tell me? What can
> I do with it? How can I change this weight? Why is the weight adjusted in
> different ways, i.e. for certain connections the weight is often set to 2,
> for others to 3, etc. And above all: Why should I change a weight, i.e.
> what could be the intention? What would this mean for "my" dataset? Between
> all origins and destinations, in our case there is weight 1. Why should I
> change it?
> Why should it make sense to change weights? In which case would I do this
> and why? What is the code for changing the weight?
>
> 11. How to calculate the following? For example, is this calculated per
> student or even per cluster (e.g. school class)? Or for which properties is
> this calculated?
> - Degree Centrality
> - Betweenness-Zentralit?t)
> - Closeness Central Office
> - Prestige Indegree
> - Ego Network
>
> 12. Link Predictions? I heard that there are ways to use different models
> (or algorithms?) to predict what other possible connections between nodes
> or the students (in our case) might look like. For example Jaccard, Common
> Neighbours, Preferential Attachment, Resource Allocation, etc. What does
> the code for these look like?
>
> I am looking forward to your feedback. Thank you very much and best regards
>
> Daniel Wobmann
>
>
>
>
>
>
>
>
>
>
>
>
> ---------- Forwarded message ----------
> From: Divya <dvsree123 at gmail.com>
> To: tutor at python.org
> Cc:
> Bcc:
> Date: Tue, 2 Jun 2020 16:40:56 +0530
> Subject: [Tutor] Practice websites
> Please suggest me some websites where I can practice the very basics like
> functions, expressions etc..
>
>
>
>
> ---------- Forwarded message ----------
> From: Alan Gauld <alan.gauld at yahoo.co.uk>
> To: tutor at python.org
> Cc:
> Bcc:
> Date: Wed, 3 Jun 2020 00:00:05 +0100
> Subject: Re: [Tutor] Practice websites
> On 02/06/2020 12:10, Divya wrote:
> > Please suggest me some websites where I can practice the very basics like
> > functions, expressions etc..
>
>
> I'm not sure what you are looking for.
>
> There are a couple of web sites with virtual Python interpreters
> where you can type basic Python code and it will execute it
> for you. If that's what you want here is one I found. I
> don't use this service so can't say how good it is but it
> seems to handle print("hello") ok...!
>
> https://repl.it/languages/Python3
>
> But most folks find it easier to download Python to their PC
> (Or tablet) and use it offline. Especially if you want to process
> local data or manipulate you machine in some way.
>
> If on the other hand you are looking for tutorial information there
> is a whole page for beginners (one each both non-programmers and
> existing programmers in other languages). (Or you can try
> mine - see the link in my .sig
>
> Finally, if you want projects or exercises there are some sites
> that do that too - I think coursera has some. And the Python
> Challenge website is an interesting way to learn new tricks
> with Python.
>
> I hope that helps, if not you need to be a bit more specific
> about what you are after.
>
> --
> 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: boB Stepp <robertvstepp at gmail.com>
> To: tutor at python.org
> Cc:
> Bcc:
> Date: Tue, 2 Jun 2020 18:12:04 -0500
> Subject: [Tutor] Named tuple special methods and attributes start with an
> underscore?
> I was reading an article on the collections library
> (
> https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html
> ).
> In it it had the following note:  "In Python, methods with leading
> underscores are usually considered ?private.? Additional methods provided
> by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are
> public."  This greatly surprised me.  So I went to the Python docs
> (https://docs.python.org/3/library/collections.html#collections.namedtuple
> )
> and found:  "In addition to the methods inherited from tuples, named tuples
> support three additional methods and two attributes. To prevent conflicts
> with field names, the method and attribute names start with an underscore."
> Huh?!?
>
> The mentioned 5 items are:  _make, _asdict, _replace, _fields and
> _field_defaults.  Of the items "_replace" is the most surprising as that is
> already used by Python in other contexts such as str.replace().  These
> items don't look to be likely field names to be used by anyone.  Any
> illumination for this design decision?  To my (perhaps naive) eyes this
> strikes me as extraordinarily inconsistent Python syntax.
>
> --
> Wishing you only the best,
>
> boB Stepp
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>

From robertvstepp at gmail.com  Fri Jun  5 21:40:15 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 5 Jun 2020 20:40:15 -0500
Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type
 annotation errors)
Message-ID: <20200606014015.GQ23247@Dream-Machine1>

Don't know why, but dn's email did not arrive in my inbox.  I am beginning
to believe that Gmail applies random filtering to writers from UK, NZ,
Australia, etc.  So I've copied and pasted from the Tutor Archives.

DL Neil wrote:
> boB wrote:
>> Peter wrote:
>> In terms of following along with Beazley's course material this would be
>> cheating.  Classes have not been presented yet.  Even very simple ones.
>> ~(:>))
>> 
>>> PPS: For someone who knows a little C the obvious fix for your version 
>>> is to
>>> cast the union to the expected type:

>This is a little difficult to rationalise:
>- we are not trying to get ahead of the course material
>- but we are prepared to launch into complex (if not complicated) mypy
>Apologies, I can see the 'why' but can't help but feel it is only that 
>imbalance which has led to the problem...

HALT!  *I* am solely responsible for mixing in type annotations, not Mr.
Beazley.  As you know I have been working on learning these.  While I am
working through his course I am practicing type annotations.  Beazley does
briefly mention type annotations, but so far he has not asked the reader of
his course to do anything with them.  Any resulting messy annotations are
the sole responsibility of daboB (*not* dabeaz).

>I'd like to discuss the (actual) problem, and then dispute the 
>claim-pursuant:

>[from another part of the thread]
><<<
>In this exercise set he wishes to create a module fileparse which can
>accept a csv-like file and allow one to obtain a list of dictionaries (one
>per file row) if the file has headers or a list of tuples if not,
>representing the collection of records.  Additionally he wishes to allow
>for setting arguments to choose only certain data columns (If the file has
>headers), do type conversions by providing a list of functions to do the
>conversions, and setting a different delimiter than the default comma.  At
>the end of the exercises he comments:

>"If you?ve made it this far, you?ve created a nice library function that?s
>genuinely useful. You can use it to parse arbitrary CSV files, select out
>columns of interest, perform type conversions, without having to worry too
>much about the inner workings of files or the csv module."
> >>>

>I'm firmly joining with others who have suggested that rather than 
>"nice" it is actually quite 'ugly'. The routine, as-is, violates the 
>Single Responsibility Principle (SRP). It is trying to deal with CSV 
>files that have column headings AND those which don't. That's not an 
>horrendous crime, per-se (but see later). However, the idea that the 
>routine will output either a list of dicts or a list of tuples, most 
>certainly is a major transgression!

Bear in mind that as I have been working my way through the material
Beazley has been gradually adding in more Python and having the reader make
modifications to already existing code that the reader has written.  To my
eyes, he has gradually been tightening up the code and making it more
realistic.  For the current function exercise that is taking quite a
beating in this forum I will report the next segment of the story.  I am
now in "3.3 Error Checking"
(https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/03_Error_checking.html).
In "Exercise 3.8:  Raising exceptions" he says:

"The parse_csv() function you wrote in the last section allows
user-specified columns to be selected, but that only works if the input
data file has column headers.

Modify the code so that an exception gets raised if both the select and
has_headers=False arguments are passed. For example:

>>> parse_csv('Data/prices.csv', select=['name','price'],
>>> has_headers=False)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
     File "fileparse.py", line 9, in parse_csv
         raise RuntimeError("select argument requires column headers")
         RuntimeError: select argument requires column headers
         >>>
"

I had wondered about this point as well as some others and was curious
whether he would address it later.  So, typically for the course so far, he
gets around to addressing this particular item.  It would not surprise me
at all if the parse_csv module eventually morphs into something less likely
to raise Tutor hackles.  I will keep you posted!

-- 
Wishing you only the best,

boB Stepp

From 1611kjb at gmail.com  Fri Jun  5 20:19:25 2020
From: 1611kjb at gmail.com (1611kjb at gmail.com)
Date: Fri, 5 Jun 2020 20:19:25 -0400
Subject: [Tutor] Beginner Noob
Message-ID: <023d01d63b98$22f22290$68d667b0$@gmail.com>

I am very green with Python. In fact, Hello World is it so far. I'm
reading/learning from a book called Python Programming for the Absolute
Beginner. My first question is real simple, looking at the UI and reading
the beginning pages, Python seems to follow in the steps of Visual Basic.
BASIC was written in the 1960's and I first ran into it in 1983 on a VIC20
computer, where I also bought a stand alone a cartridge and learned about
machine language. In any event, when it started, BASIC was an interpreted
language. You couldn't run a program stand alone. You had to buy an
interpreter, then create a numbered, formatted ASCII text file which the
interpreter read and executed line by line. Eventually Microsoft created
Visual Basic with a graphical UI and a runtime package and now you can do
most things in VB if you like. Python seems to be running this same
gauntlet. I can run/test it through a Python Interpreter or it can be
compiled into a runtime. At the moment I am learning using the Python 3.8.3
shell from the Microsoft Store and I have installed the Python branch to
Visual Studio Community Edition.

 

Whew, I'm long winded, I say all that to ask, what are the advantages to
jumping over to Python from VB? I am simultaneously working on C# and
wondering if it's worth taxing myself to learn another language. I started
it because I am working with Mindstorms EV3 robotics kits, there educational
platform for K12 education, Arduino controllers and Raspberry PI computers.
They all seem to like Python and C, C++ and C#. I'm an old retired guy
stretching the grey muscles and just wondering if this is a good way to
apply myself. Thanks for any input. I'm sure I'll br here a lot.

 

---Mike

 


From jf_byrnes at comcast.net  Fri Jun  5 21:01:14 2020
From: jf_byrnes at comcast.net (Jim)
Date: Fri, 5 Jun 2020 20:01:14 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
Message-ID: <rbepsr$hj2$1@ciao.gmane.io>

Mint18.3, python3.6, pandas 0.24.1


et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, 
engine='python')
df.to_clipboard(sep=',')
print(df)

Manual notes the following. I'm not using PyQt4, but xclip is installed.

Notes: Requirements for your platform.

     Linux : xclip, or xsel (with PyQt4 modules)
     Windows : none
     OS X : none

The print command prints what I expect to see.

I don't use pandas that much so maybe I am missing something.

Thanks, Jim


From manpritsinghece at gmail.com  Sat Jun  6 00:11:19 2020
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sat, 6 Jun 2020 09:41:19 +0530
Subject: [Tutor] Question regarding use of assignment expression in python
 3.8.3
Message-ID: <CAO1OCwYnHkRJJ_otEk6jHOBfKUbOkBEw9EX+MYXThx3VKrxRLw@mail.gmail.com>

Dear all,

According to Heron's formula for finding area of a triangle , if the sides
of a triangle  are a, b & c is :
s = (a+b+c) / 2
area =sqrt( s * (s-a) * (s-b) * (s-c))   // sqrt means square root

so for finding the area of the triangle using Heron's formula in Python ,
if i write code like this , will it be a valid practise ?
I have used assignment expression while calculating the  area

a = int(input("Enter value of first side"))                     // Assuming
value is integer
b = int(input("Enter value of second side"))               // Assuming
value is integer
c = int(input("Enter value of third side"))                   // Assuming
value is integer
area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5
print("Area of the triangle is", area)

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Sat Jun  6 03:39:39 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 6 Jun 2020 08:39:39 +0100
Subject: [Tutor] Question regarding use of assignment expression in
 python 3.8.3
In-Reply-To: <CAO1OCwYnHkRJJ_otEk6jHOBfKUbOkBEw9EX+MYXThx3VKrxRLw@mail.gmail.com>
References: <CAO1OCwYnHkRJJ_otEk6jHOBfKUbOkBEw9EX+MYXThx3VKrxRLw@mail.gmail.com>
Message-ID: <rbfh7r$a19$1@ciao.gmane.io>

On 06/06/2020 05:11, Manprit Singh wrote:

> so for finding the area of the triangle using Heron's formula in Python ,
> if i write code like this , will it be a valid practise ?

Yes, if you just want to practice use of assignment expressions.

> area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5

Its syntactically valid to use it here but offers very no
advantage over a separate assignment line

s = a+b+c

And has 2 minor disadvantages:
1) its more typing (2 keystrokes)
2) its harder to debug - no way to inspect s prior to executing
   the calculation.

-- 
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 Jun  6 03:58:56 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 6 Jun 2020 08:58:56 +0100
Subject: [Tutor] Beginner Noob
In-Reply-To: <023d01d63b98$22f22290$68d667b0$@gmail.com>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
Message-ID: <rbfic0$2l5b$1@ciao.gmane.io>

On 06/06/2020 01:19, 1611kjb at gmail.com wrote:

> Whew, I'm long winded, I say all that to ask, what are the advantages to
> jumping over to Python from VB? 

Python is a more modern language with more powerful data structures and
language constructs. Although with modern VB.Net that's less of an
argument. Python also has an awesome standard library and third-party
supported ecosystem.

> I am simultaneously working on C# and
> wondering if it's worth taxing myself to learn another language. 

Every language teaches lessons that you can apply in every other
language. Some teach more than others - Lisp, Smalltalk, Prolog, etc

C# is a traditional language in the same vein as C/C++/Pascal/Java.
It's very good for large projects (100k+ lines) involving many
programmers. But it requires a lot of planning and design at a detailed
level to use effectively.

Python is designed for rapid implementation. It's not as fast in
execution but it can be thrown together in a more experimental
fashion. Before I retired I used Python as a prototyping language
before handing designs over to our contractor programmers who were
using Java. Of course Python can be used in production code too
with a little extra care.

VB sits somewhere between those two on the technology continuum
Faster to write than C#, not as fast as Python(unless you are
building GUIs) but not as powerful as C# either. (I may be wrong
but I get the impression that VB.Net is slowly fading away.
C# has closed the gap to the point where VB's advantages have
been eroded.)


> platform for K12 education, Arduino controllers and Raspberry PI computers.
> They all seem to like Python and C, C++ and C#. I'm an old retired guy
> stretching the grey muscles and just wondering if this is a good way to
> apply myself. Thanks for any input. I'm sure I'll br here a lot.
Python is used in all these areas and is generally considered easier
to learn than C# and certainly C++. I would only recommend C++ if you
are tinkering at the machine level - its the natural partner for an
Arduino for example. C# (and Java) are similar to C++ but more
focused on higher level application code. C++ compiles to native
machine code. All the others compile to bytecode which is then
interpreted. For normal human interactive programs it makes little
difference on modern computers. If you are writing a high data
volume server or a piece of hardware interface then speed may
become an issue and c++ wins. But at the expense of much harder
to write, test and debug code.


-- 
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 PyTutor at danceswithmice.info  Sat Jun  6 04:38:15 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Sat, 6 Jun 2020 20:38:15 +1200
Subject: [Tutor] Beginner Noob
In-Reply-To: <023d01d63b98$22f22290$68d667b0$@gmail.com>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
Message-ID: <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>

On 6/06/20 12:19 PM, 1611kjb at gmail.com wrote:
> I am very green with Python. In fact, Hello World is it so far. I'm
> reading/learning from a book called Python Programming for the Absolute
> Beginner. My first question is real simple, looking at the UI and reading
> the beginning pages, Python seems to follow in the steps of Visual Basic.
> BASIC was written in the 1960's and I first ran into it in 1983 on a VIC20
> computer, where I also bought a stand alone a cartridge and learned about
> machine language. In any event, when it started, BASIC was an interpreted
> language. You couldn't run a program stand alone. You had to buy an
> interpreter, then create a numbered, formatted ASCII text file which the
> interpreter read and executed line by line. Eventually Microsoft created
> Visual Basic with a graphical UI and a runtime package and now you can do
> most things in VB if you like. Python seems to be running this same
> gauntlet. I can run/test it through a Python Interpreter or it can be
> compiled into a runtime. At the moment I am learning using the Python 3.8.3
> shell from the Microsoft Store and I have installed the Python branch to
> Visual Studio Community Edition.
> 
>   
> 
> Whew, I'm long winded, I say all that to ask, what are the advantages to
> jumping over to Python from VB? I am simultaneously working on C# and
> wondering if it's worth taxing myself to learn another language. I started
> it because I am working with Mindstorms EV3 robotics kits, there educational
> platform for K12 education, Arduino controllers and Raspberry PI computers.
> They all seem to like Python and C, C++ and C#. I'm an old retired guy
> stretching the grey muscles and just wondering if this is a good way to
> apply myself. Thanks for any input. I'm sure I'll br here a lot.


Further to Alan's comments:-
(I often cast myself as offering a contrary view to his - fortunately we 
live far-enough apart that he can't toss his caber at me. Such is one of 
the advantages of the community here - ask one question but receive 
answers from different perspectives or based upon different 
interpretations!)

There is a MicroPython which works well on Raspberry Pi SBCs, whereas 
there is a version of C which is native to the Arduino.

Another 'trick', which may be open to you, is developing code on a 
larger (lap-top or desk-top) machine (with many more 
dev/debugging/testing facilities) and only transferring the code into 
the SBC once it is basically (or completely) working!

A concern is that it can be confusing trying to learn two languages at 
once - and a fairly-similar, but significantly-different, pair at that. 
Recommend one at a time! So, depending upon which SBC you've already 
purchased/plan to buy first, go with the applicable language (and then 
pick-up the other when you move-on to the next project)...

As Alan said, having learned one language it is relatively easy to learn 
another. However, try to resist the temptation to 'see' Python in terms 
of VB. Even where the commands are the same word, they may not perform 
in exactly the same way. On top of that, we talk about "idioms" which 
are quite different - implementing a noticeably different set of 
philosophies from VB specifically, and MSFT in general.

I like Python because there is no intermediate step - one writes some 
code and it will runs. The benefits of immediacy can hardly be 
under-stated. The only issues in the environments you've mentioned, are 
things like running-out of storage space - but there are multiple ways 
to deal with such challenges...

Yes, good to keep the grey-cells receptive, and we'll look forward to 
seeing more of what you get up-to (Silver-surfers of the world unite!)
-- 
Regards =dn

From __peter__ at web.de  Sat Jun  6 05:25:19 2020
From: __peter__ at web.de (Peter Otten)
Date: Sat, 06 Jun 2020 11:25:19 +0200
Subject: [Tutor] pandas.to_clipboard() copies nothing
References: <rbepsr$hj2$1@ciao.gmane.io>
Message-ID: <rbfne0$1993$1@ciao.gmane.io>

Jim wrote:

> Mint18.3, python3.6, pandas 0.24.1
> 
> 
> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
> engine='python')
> df.to_clipboard(sep=',')
> print(df)
> 
> Manual notes the following. I'm not using PyQt4, but xclip is installed.
> 
> Notes: Requirements for your platform.
> 
>      Linux : xclip, or xsel (with PyQt4 modules)
>      Windows : none
>      OS X : none
> 
> The print command prints what I expect to see.
> 
> I don't use pandas that much so maybe I am missing something.

The pandas side seems OK; maybe you are looking at the wrong selection?
I have a slightly different setup, and the following works for me:

$ python3
Python 3.4.3 (default, Nov 12 2018, 22:25:49) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"])
>>> df.to_clipboard(sep=", ")
>>> 
$ xclip -o -selection clipboard
   Ham  Spam
0    1     2
1    3     4$ 



From __peter__ at web.de  Sat Jun  6 05:47:12 2020
From: __peter__ at web.de (Peter Otten)
Date: Sat, 06 Jun 2020 11:47:12 +0200
Subject: [Tutor] pandas.to_clipboard() copies nothing
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
Message-ID: <rbfon1$3vp2$1@ciao.gmane.io>

Peter Otten wrote:

> I have a slightly different setup, and the following works for me:
> 
> $ python3
> Python 3.4.3 (default, Nov 12 2018, 22:25:49)
> [GCC 4.8.4] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import pandas
>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"])
>>>> df.to_clipboard(sep=", ")
>>>> 
> $ xclip -o -selection clipboard
>    Ham  Spam
> 0    1     2
> 1    3     4$

Except that the 2-char sep is ignored ;)


From jf_byrnes at comcast.net  Sat Jun  6 11:29:58 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 6 Jun 2020 10:29:58 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <rbfne0$1993$1@ciao.gmane.io>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
Message-ID: <rbgcpn$2qid$1@ciao.gmane.io>

On 6/6/20 4:25 AM, Peter Otten wrote:
> Jim wrote:
> 
>> Mint18.3, python3.6, pandas 0.24.1
>>
>>
>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
>> engine='python')
>> df.to_clipboard(sep=',')
>> print(df)
>>
>> Manual notes the following. I'm not using PyQt4, but xclip is installed.
>>
>> Notes: Requirements for your platform.
>>
>>       Linux : xclip, or xsel (with PyQt4 modules)
>>       Windows : none
>>       OS X : none
>>
>> The print command prints what I expect to see.
>>
>> I don't use pandas that much so maybe I am missing something.
> 
> The pandas side seems OK; maybe you are looking at the wrong selection?
> I have a slightly different setup, and the following works for me:
> 
> $ python3
> Python 3.4.3 (default, Nov 12 2018, 22:25:49)
> [GCC 4.8.4] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import pandas
>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"])
>>>> df.to_clipboard(sep=", ")
>>>>
> $ xclip -o -selection clipboard
>     Ham  Spam
> 0    1     2
> 1    3     4$
> 

Peter,

I'm not sure what you mean by the "wrong selection" above. I ran your 
code and got the following results.


This version (space after ,) worked despite the error msg:

Python 3.6.10 (default, Dec 19 2019, 23:04:32)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
 >>> import pandas
 >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"])
 >>> df.to_clipboard(sep=", ")
QApplication: invalid style override passed, ignoring it.
     Available styles: Windows, Fusion
/home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: 
UserWarning: to_clipboard in excel mode requires a single character 
separator.
   warnings.warn('to_clipboard in excel mode requires a single '

Copied from clipboard:
    Ham  Spam
0    1     2
1    3     3

This version (no space after ,) also worked despite a different error msg:

(env36) jfb at jims-mint18 ~ $ python
Python 3.6.10 (default, Dec 19 2019, 23:04:32)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
 >>> import pandas
 >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"])
 >>> df.to_clipboard(sep=",")
QApplication: invalid style override passed, ignoring it.
     Available styles: Windows, Fusion

Copied from clipboard:
,Ham,Spam
0,1,2
1,3,4


I had a little test file I was using to figure out pandas so I dropped 
your code in it. Nothing was copied to the clipboard and this is the 
error msg:

(env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
QApplication: invalid style override passed, ignoring it.
     Available styles: Windows, Fusion
/home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: 
UserWarning: to_clipboard in excel mode requires a single character 
separator.
   warnings.warn('to_clipboard in excel mode requires a single '

So I added excel=False and dropped the sep= and got this error:

(env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
QApplication: invalid style override passed, ignoring it.
     Available styles: Windows, Fusion

I don't understand the QApplication reference. I assume it refers to QT 
I have some QT stuff installed:

from pip list:
PyQt5                    5.12
PyQt5-sip                4.19.14
qtconsole                4.4.3

I don't know why QT would come into play here and I don't understand the 
reference to excel when it was not included.

To sum up. If I run it from the python console it give an error, but 
copies to the clipboard. If I run the python file from the terminal it 
gives an error and does not copy to the clipboard.

Thanks, Jim



From __peter__ at web.de  Sat Jun  6 14:39:59 2020
From: __peter__ at web.de (Peter Otten)
Date: Sat, 06 Jun 2020 20:39:59 +0200
Subject: [Tutor] pandas.to_clipboard() copies nothing
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io>
Message-ID: <rbgnu0$29ac$1@ciao.gmane.io>

Jim wrote:

> On 6/6/20 4:25 AM, Peter Otten wrote:
>> Jim wrote:
>> 
>>> Mint18.3, python3.6, pandas 0.24.1
>>>
>>>
>>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
>>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
>>> engine='python')
>>> df.to_clipboard(sep=',')
>>> print(df)
>>>
>>> Manual notes the following. I'm not using PyQt4, but xclip is installed.
>>>
>>> Notes: Requirements for your platform.
>>>
>>>       Linux : xclip, or xsel (with PyQt4 modules)
>>>       Windows : none
>>>       OS X : none
>>>
>>> The print command prints what I expect to see.
>>>
>>> I don't use pandas that much so maybe I am missing something.
>> 
>> The pandas side seems OK; maybe you are looking at the wrong selection?
>> I have a slightly different setup, and the following works for me:
>> 
>> $ python3
>> Python 3.4.3 (default, Nov 12 2018, 22:25:49)
>> [GCC 4.8.4] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> import pandas
>>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"])
>>>>> df.to_clipboard(sep=", ")
>>>>>
>> $ xclip -o -selection clipboard
>>     Ham  Spam
>> 0    1     2
>> 1    3     4$
>> 
> 
> Peter,
> 
> I'm not sure what you mean by the "wrong selection" above. I ran your
> code and got the following results.
> 
> 
> This version (space after ,) worked despite the error msg:
> 
> Python 3.6.10 (default, Dec 19 2019, 23:04:32)
> [GCC 5.4.0 20160609] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import pandas
>  >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"])
>  >>> df.to_clipboard(sep=", ")
> QApplication: invalid style override passed, ignoring it.
>      Available styles: Windows, Fusion
> /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134:
> UserWarning: to_clipboard in excel mode requires a single character
> separator.
>    warnings.warn('to_clipboard in excel mode requires a single '
> 
> Copied from clipboard:
>     Ham  Spam
> 0    1     2
> 1    3     3
> 
> This version (no space after ,) also worked despite a different error msg:
> 
> (env36) jfb at jims-mint18 ~ $ python
> Python 3.6.10 (default, Dec 19 2019, 23:04:32)
> [GCC 5.4.0 20160609] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import pandas
>  >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"])
>  >>> df.to_clipboard(sep=",")
> QApplication: invalid style override passed, ignoring it.
>      Available styles: Windows, Fusion
> 
> Copied from clipboard:
> ,Ham,Spam
> 0,1,2
> 1,3,4
> 
> 
> I had a little test file I was using to figure out pandas so I dropped
> your code in it. Nothing was copied to the clipboard and this is the
> error msg:
> 
> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
> QApplication: invalid style override passed, ignoring it.
>      Available styles: Windows, Fusion
> /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134:
> UserWarning: to_clipboard in excel mode requires a single character
> separator.
>    warnings.warn('to_clipboard in excel mode requires a single '
> 
> So I added excel=False and dropped the sep= and got this error:
> 
> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
> QApplication: invalid style override passed, ignoring it.
>      Available styles: Windows, Fusion
> 
> I don't understand the QApplication reference. I assume it refers to QT
> I have some QT stuff installed:
> 
> from pip list:
> PyQt5                    5.12
> PyQt5-sip                4.19.14
> qtconsole                4.4.3
> 
> I don't know why QT would come into play here and I don't understand the
> reference to excel when it was not included.
> 
> To sum up. If I run it from the python console it give an error, but
> copies to the clipboard. If I run the python file from the terminal it
> gives an error and does not copy to the clipboard.

Most of your errors seem to be warnings.

Looking into the code writing to the clipboard shows that it requires the 
DISPLAY environment variable to be set, so I'd check that in the terminal.

https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539

shows that

    if HAS_DISPLAY:
        if _executable_exists("xsel"):
            return init_xsel_clipboard()
        if _executable_exists("xclip"):
            return init_xclip_clipboard()
        if _executable_exists("klipper") and _executable_exists("qdbus"):
            return init_klipper_clipboard()
        ... [try qt] 

QT is the last option. From that we can conclude that xclip is not found.
Maybe you can fix that by adjusting the path. 
Or you try to set the clipboard mechanism explicitly with

pandas.io.clipboard.set_clipboard("xclip")



From robertvstepp at gmail.com  Sat Jun  6 15:13:10 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 14:13:10 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <rbgnu0$29ac$1@ciao.gmane.io>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
Message-ID: <CANDiX9L3n3B76-rKR6XwrrAOsB2fTnNQK74pE2Df76AuJWKevw@mail.gmail.com>

On Sat, Jun 6, 2020 at 1:40 PM Peter Otten <__peter__ at web.de> wrote:
>
> Jim wrote:
>
> > On 6/6/20 4:25 AM, Peter Otten wrote:
> >> Jim wrote:
> >>
> >>> Mint18.3, python3.6, pandas 0.24.1
> >>>
> >>>
> >>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
> >>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
> >>> engine='python')
> >>> df.to_clipboard(sep=',')
> >>> print(df)
> >>>
> >>> Manual notes the following. I'm not using PyQt4, but xclip is installed.
> >>>
> >>> Notes: Requirements for your platform.
> >>>
> >>>       Linux : xclip, or xsel (with PyQt4 modules)
> >>>       Windows : none
> >>>       OS X : none

> > To sum up. If I run it from the python console it give an error, but
> > copies to the clipboard. If I run the python file from the terminal it
> > gives an error and does not copy to the clipboard.
>
> Most of your errors seem to be warnings.
>
> Looking into the code writing to the clipboard shows that it requires the
> DISPLAY environment variable to be set, so I'd check that in the terminal.
>
> https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539
>
> shows that
>
>     if HAS_DISPLAY:
>         if _executable_exists("xsel"):
>             return init_xsel_clipboard()
>         if _executable_exists("xclip"):
>             return init_xclip_clipboard()
>         if _executable_exists("klipper") and _executable_exists("qdbus"):
>             return init_klipper_clipboard()
>         ... [try qt]
>
> QT is the last option. From that we can conclude that xclip is not found.
> Maybe you can fix that by adjusting the path.
> Or you try to set the clipboard mechanism explicitly with
>
> pandas.io.clipboard.set_clipboard("xclip")

I don't know if this is relevant or not, but when I installed Neovim
on my PC I found that I could not access the system clipboard from
within Neovim.  Investigation discovered that xsel was not installed.
Like Jim I am using Linux Mint.  Once I installed xsel those problems
went away.  I cannot recall if I had to do any special configurations
for xsel or not.



-- 
boB

From jf_byrnes at comcast.net  Sat Jun  6 17:26:57 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 6 Jun 2020 16:26:57 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <CANDiX9L3n3B76-rKR6XwrrAOsB2fTnNQK74pE2Df76AuJWKevw@mail.gmail.com>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
 <CANDiX9L3n3B76-rKR6XwrrAOsB2fTnNQK74pE2Df76AuJWKevw@mail.gmail.com>
Message-ID: <rbh1n1$3f3u$1@ciao.gmane.io>

On 6/6/20 2:13 PM, boB Stepp wrote:
> On Sat, Jun 6, 2020 at 1:40 PM Peter Otten <__peter__ at web.de> wrote:
>>
>> Jim wrote:
>>
>>> On 6/6/20 4:25 AM, Peter Otten wrote:
>>>> Jim wrote:
>>>>
>>>>> Mint18.3, python3.6, pandas 0.24.1
>>>>>
>>>>>
>>>>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
>>>>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
>>>>> engine='python')
>>>>> df.to_clipboard(sep=',')
>>>>> print(df)
>>>>>
>>>>> Manual notes the following. I'm not using PyQt4, but xclip is installed.
>>>>>
>>>>> Notes: Requirements for your platform.
>>>>>
>>>>>        Linux : xclip, or xsel (with PyQt4 modules)
>>>>>        Windows : none
>>>>>        OS X : none
> 
>>> To sum up. If I run it from the python console it give an error, but
>>> copies to the clipboard. If I run the python file from the terminal it
>>> gives an error and does not copy to the clipboard.
>>
>> Most of your errors seem to be warnings.
>>
>> Looking into the code writing to the clipboard shows that it requires the
>> DISPLAY environment variable to be set, so I'd check that in the terminal.
>>
>> https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539
>>
>> shows that
>>
>>      if HAS_DISPLAY:
>>          if _executable_exists("xsel"):
>>              return init_xsel_clipboard()
>>          if _executable_exists("xclip"):
>>              return init_xclip_clipboard()
>>          if _executable_exists("klipper") and _executable_exists("qdbus"):
>>              return init_klipper_clipboard()
>>          ... [try qt]
>>
>> QT is the last option. From that we can conclude that xclip is not found.
>> Maybe you can fix that by adjusting the path.
>> Or you try to set the clipboard mechanism explicitly with
>>
>> pandas.io.clipboard.set_clipboard("xclip")
> 
> I don't know if this is relevant or not, but when I installed Neovim
> on my PC I found that I could not access the system clipboard from
> within Neovim.  Investigation discovered that xsel was not installed.
> Like Jim I am using Linux Mint.  Once I installed xsel those problems
> went away.  I cannot recall if I had to do any special configurations
> for xsel or not.


Bob,

See my last reply to Peter (it hasn't shown up yet as I write this).

xclip and xsel are installed. I got it to work by deleting the QT stuff 
from my virtual environment.

Regards,  Jim




From robertvstepp at gmail.com  Sat Jun  6 21:47:43 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 20:47:43 -0500
Subject: [Tutor] Still not understanding passing filenames in Python
Message-ID: <20200607014743.GA10604@Dream-Machine1>

Now in "3.4 Modules" at
https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html

Earlier in the course I wrote a program, report.py, that runs as so:

bob at Dream-Machine1:~/practical-python/Work$ python3 report.py

Enter path to portfolio file:  Data/portfolio.csv
Enter path to stock prices file:  Data/prices.csv

       Name     Shares      Price     Change 
---------- ---------- ---------- ---------- 
         AA        100      $9.22     -22.98
        IBM         50    $106.28      15.18
        CAT        150     $35.46     -47.98
       MSFT        200     $20.89     -30.34
         GE         95     $13.48     -26.89
       MSFT         50     $20.89     -44.21
        IBM        100    $106.28      35.84

Current portfolio value = $28,686.10
Current portfolio gain/loss = $-15,985.05

In "Exercise 3.12: Using your library module" Beazley has us importing the
recently discussed fileparse module containing the parse_csv() function to
replace the code previously written in the read_portfolio() function in
report.py.  So I added "import fileparse" and modified the read_portfolio()
function to:

def read_portfolio(filename: str) -> List[Dict[str, Union[str, int, float]]]:
     """Read a file and return a portfolio list of records."""
     portfolio = fileparse.parse_csv(
         filename, select=["name", "shares", "price"], types=[str, int, float]
     )
     return portfolio

report.py and fileparse.py are both in the same Work directory.  Data is a
subdirectory of Work.

But when I try to run this program with the same file location entries
I get:

bob at Dream-Machine1:~/practical-python/Work$ python3 report.py

Enter path to portfolio file:  Data/porfolio.csv
Enter path to stock prices file:  Data/prices.csv
Traceback (most recent call last):
   File "report.py", line 113, in <module>
     main()
   File "report.py", line 104, in main
     portfolio = read_portfolio(portfolio_path)
   File "report.py", line 18, in read_portfolio
     filename, select=["name", "shares", "price"], types=[str, int, float]
   File "/home/bob/practical-python/Work/fileparse.py", line 25, in parse_csv
     with open(filename) as fileobj:
FileNotFoundError: [Errno 2] No such file or directory: 'Data/porfolio.csv'

If I use absolute file paths, "/home/bob/practical-python..." it works.

If I use "./Data/portfolio.csv" and "./Data/prices.csv" it works.  I
currently do not understand the differences.  Obviously I do understand one
or more things.  A helpful explanation please?  Thanks!

-- 
Wishing you only the best,

boB Stepp

From PyTutor at danceswithmice.info  Sat Jun  6 22:19:09 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Sun, 7 Jun 2020 14:19:09 +1200
Subject: [Tutor] Still not understanding passing filenames in Python
In-Reply-To: <20200607014743.GA10604@Dream-Machine1>
References: <20200607014743.GA10604@Dream-Machine1>
Message-ID: <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info>

On 7/06/20 1:47 PM, boB Stepp wrote:
> Now in "3.4 Modules" at
> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html 
> 
> 
> Earlier in the course I wrote a program, report.py, that runs as so:
> 
> bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
> 
> Enter path to portfolio file:? Data/portfolio.csv
> Enter path to stock prices file:? Data/prices.csv
> 
>  ????? Name???? Shares????? Price???? Change ---------- ---------- 
> ---------- ---------- ??????? AA??????? 100????? $9.22???? -22.98
>  ?????? IBM???????? 50??? $106.28????? 15.18
>  ?????? CAT??????? 150???? $35.46???? -47.98
>  ????? MSFT??????? 200???? $20.89???? -30.34
>  ??????? GE???????? 95???? $13.48???? -26.89
>  ????? MSFT???????? 50???? $20.89???? -44.21
>  ?????? IBM??????? 100??? $106.28????? 35.84
> 
> Current portfolio value = $28,686.10
> Current portfolio gain/loss = $-15,985.05
> 
> In "Exercise 3.12: Using your library module" Beazley has us importing the
> recently discussed fileparse module containing the parse_csv() function to
> replace the code previously written in the read_portfolio() function in
> report.py.? So I added "import fileparse" and modified the read_portfolio()
> function to:
> 
> def read_portfolio(filename: str) -> List[Dict[str, Union[str, int, 
> float]]]:
>  ??? """Read a file and return a portfolio list of records."""
>  ??? portfolio = fileparse.parse_csv(
>  ??????? filename, select=["name", "shares", "price"], types=[str, int, 
> float]
>  ??? )
>  ??? return portfolio
> 
> report.py and fileparse.py are both in the same Work directory.? Data is a
> subdirectory of Work.
> 
> But when I try to run this program with the same file location entries
> I get:
> 
> bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
> 
> Enter path to portfolio file:? Data/porfolio.csv
> Enter path to stock prices file:? Data/prices.csv
> Traceback (most recent call last):
>  ? File "report.py", line 113, in <module>
>  ??? main()
>  ? File "report.py", line 104, in main
>  ??? portfolio = read_portfolio(portfolio_path)
>  ? File "report.py", line 18, in read_portfolio
>  ??? filename, select=["name", "shares", "price"], types=[str, int, float]
>  ? File "/home/bob/practical-python/Work/fileparse.py", line 25, in 
> parse_csv
>  ??? with open(filename) as fileobj:
> FileNotFoundError: [Errno 2] No such file or directory: 'Data/porfolio.csv'
> 
> If I use absolute file paths, "/home/bob/practical-python..." it works.
> 
> If I use "./Data/portfolio.csv" and "./Data/prices.csv" it works.? I
> currently do not understand the differences.? Obviously I do understand one
> or more things.? A helpful explanation please?? Thanks!


Please don't shoot the piano player (or the Latin teacher)...
is the fileNM correct?

 > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
 >
 > Enter path to portfolio file:  Data/portfolio.csv

...

 > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
 >
 > Enter path to portfolio file:  Data/porfolio.csv
-- 
Regards =dn

From robertvstepp at gmail.com  Sat Jun  6 22:19:47 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 21:19:47 -0500
Subject: [Tutor] Unnecessary comprehension warning
Message-ID: <20200607021947.GB10604@Dream-Machine1>

Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html.

I rewrote another function in report.py, read_prices(), to make use of the
parse_csv() function in the fileparse module.  The rewritten function is:

def read_prices(filename: str) -> Dict[str, float]:
     """Read a file of stock prices and load them into a dictionary."""
     prices = fileparse.parse_csv(filename, types=[str, float], has_headers=False)
     stock_prices = {stock_name: stock_price for stock_name, stock_price in prices}
     return stock_prices

pylint complains with:

report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use of a comprehension

The dictionary comprehension I'm now using replaces a lengthier for loop
with indexing instead of nice names.  Am I truly doing things in a bad
Python style as the linter is complaining?  Should I be doing this
differently?

-- 
Wishing you only the best,

boB Stepp

From PyTutor at danceswithmice.info  Sat Jun  6 22:29:24 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Sun, 7 Jun 2020 14:29:24 +1200
Subject: [Tutor] Unnecessary comprehension warning
In-Reply-To: <20200607021947.GB10604@Dream-Machine1>
References: <20200607021947.GB10604@Dream-Machine1>
Message-ID: <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>

On 7/06/20 2:19 PM, boB Stepp wrote:
> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. 
> 
> 
> I rewrote another function in report.py, read_prices(), to make use of the
> parse_csv() function in the fileparse module.? The rewritten function is:
> 
> def read_prices(filename: str) -> Dict[str, float]:
>  ??? """Read a file of stock prices and load them into a dictionary."""
>  ??? prices = fileparse.parse_csv(filename, types=[str, float], 
> has_headers=False)
>  ??? stock_prices = {stock_name: stock_price for stock_name, stock_price 
> in prices}
>  ??? return stock_prices
> 
> pylint complains with:
> 
> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use 
> of a comprehension
> 
> The dictionary comprehension I'm now using replaces a lengthier for loop
> with indexing instead of nice names.? Am I truly doing things in a bad
> Python style as the linter is complaining?? Should I be doing this
> differently?


The name "prices" is defined and then used, but enjoys no further reference.

What happens (from PyLint's PoV) if you make the two lines into one?
(overly-complicated and ugly though it would be)
-- 
Regards =dn

From PyTutor at danceswithmice.info  Sat Jun  6 22:45:24 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Sun, 7 Jun 2020 14:45:24 +1200
Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type
 annotation errors)
In-Reply-To: <20200606014015.GQ23247@Dream-Machine1>
References: <20200606014015.GQ23247@Dream-Machine1>
Message-ID: <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info>

On 6/06/20 1:40 PM, boB Stepp wrote:
> DL Neil wrote:
>> boB wrote:
>>> Peter wrote:
>>> In terms of following along with Beazley's course material this would be
>>> cheating.? Classes have not been presented yet.? Even very simple ones.
>>> ~(:>))
>>>
>>>> PPS: For someone who knows a little C the obvious fix for your 
>>>> version is to
>>>> cast the union to the expected type:
> 
>> This is a little difficult to rationalise:
>> - we are not trying to get ahead of the course material
>> - but we are prepared to launch into complex (if not complicated) mypy
>> Apologies, I can see the 'why' but can't help but feel it is only that 
>> imbalance which has led to the problem...
> 
> HALT!? *I* am solely responsible for mixing in type annotations, not Mr.
> Beazley.? As you know I have been working on learning these.? While I am
> working through his course I am practicing type annotations.? Beazley does
> briefly mention type annotations, but so far he has not asked the reader of
> his course to do anything with them.? Any resulting messy annotations are
> the sole responsibility of daboB (*not* dabeaz).

Understood, and that's the point: having accepted the assignment's 
status as 'incomplete' (and without typing), it has then had advanced 
typing techniques applied. There lies the imbalance.

Further, adding class technology to the assignment was described as 
"cheating" - because it is a future topic (one expects). Yet advanced 
typing, also not/yet to be covered in the course, is not "cheating"?

Given that 'the other David' has been a trainer almost as long as I (but 
he as a Python trainer - which I am (formally) not!), it seemed 
reasonable teaching technique/planning that the course would build 
further (per more-recent messages to this list). Perhaps the assertion 
of it being a useful utility back-then, was somewhat premature, and 
better applied to its 'final' iteration of development?
-- 
Regards =dn

From robertvstepp at gmail.com  Sat Jun  6 22:50:34 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 21:50:34 -0500
Subject: [Tutor] Still not understanding passing filenames in Python
In-Reply-To: <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info>
References: <20200607014743.GA10604@Dream-Machine1>
 <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info>
Message-ID: <CANDiX9Kq9VoT7dFO-THMnmABC9spfgV_5Oi966gdt0jx9hWEUA@mail.gmail.com>

On Sat, Jun 6, 2020 at 9:19 PM DL Neil via Tutor <tutor at python.org> wrote:
>
> On 7/06/20 1:47 PM, boB Stepp wrote:

> Please don't shoot the piano player (or the Latin teacher)...
> is the fileNM correct?
>
>  > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
>  >
>  > Enter path to portfolio file:  Data/portfolio.csv
>
> ...
>
>  > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py
>  >
>  > Enter path to portfolio file:  Data/porfolio.csv

You don't know how many times I read and reread these lines!  Don't
worry, your safety is ensured.  New computer glasses may be in order
though.

Thanks!

-- 
boB

From robertvstepp at gmail.com  Sat Jun  6 23:00:09 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 22:00:09 -0500
Subject: [Tutor] Unnecessary comprehension warning
In-Reply-To: <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>
References: <20200607021947.GB10604@Dream-Machine1>
 <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>
Message-ID: <CANDiX9KByxor4+7VWBbij1HcregFsYjGTD3aTDZOgYH8rrbMzw@mail.gmail.com>

On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor <tutor at python.org> wrote:
>
> On 7/06/20 2:19 PM, boB Stepp wrote:
> > Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
> > https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html.
> >
> >
> > I rewrote another function in report.py, read_prices(), to make use of the
> > parse_csv() function in the fileparse module.  The rewritten function is:
> >
> > def read_prices(filename: str) -> Dict[str, float]:
> >      """Read a file of stock prices and load them into a dictionary."""
> >      prices = fileparse.parse_csv(filename, types=[str, float],
> > has_headers=False)
> >      stock_prices = {stock_name: stock_price for stock_name, stock_price
> > in prices}
> >      return stock_prices
> >
> > pylint complains with:
> >
> > report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use
> > of a comprehension
> >
> > The dictionary comprehension I'm now using replaces a lengthier for loop
> > with indexing instead of nice names.  Am I truly doing things in a bad
> > Python style as the linter is complaining?  Should I be doing this
> > differently?
>
>
> The name "prices" is defined and then used, but enjoys no further reference.
>
> What happens (from PyLint's PoV) if you make the two lines into one?
> (overly-complicated and ugly though it would be)

Strangely, it makes no difference, same warning.



-- 
boB

From PyTutor at danceswithmice.info  Sat Jun  6 23:13:42 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Sun, 7 Jun 2020 15:13:42 +1200
Subject: [Tutor] Unnecessary comprehension warning
In-Reply-To: <CANDiX9KByxor4+7VWBbij1HcregFsYjGTD3aTDZOgYH8rrbMzw@mail.gmail.com>
References: <20200607021947.GB10604@Dream-Machine1>
 <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>
 <CANDiX9KByxor4+7VWBbij1HcregFsYjGTD3aTDZOgYH8rrbMzw@mail.gmail.com>
Message-ID: <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info>

On 7/06/20 3:00 PM, boB Stepp wrote:
> On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor <tutor at python.org> wrote:
>>
>> On 7/06/20 2:19 PM, boB Stepp wrote:
>>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
>>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html.
>>>
>>>
>>> I rewrote another function in report.py, read_prices(), to make use of the
>>> parse_csv() function in the fileparse module.  The rewritten function is:
>>>
>>> def read_prices(filename: str) -> Dict[str, float]:
>>>       """Read a file of stock prices and load them into a dictionary."""
>>>       prices = fileparse.parse_csv(filename, types=[str, float],
>>> has_headers=False)
>>>       stock_prices = {stock_name: stock_price for stock_name, stock_price
>>> in prices}
>>>       return stock_prices
>>>
>>> pylint complains with:
>>>
>>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use
>>> of a comprehension
>>>
>>> The dictionary comprehension I'm now using replaces a lengthier for loop
>>> with indexing instead of nice names.  Am I truly doing things in a bad
>>> Python style as the linter is complaining?  Should I be doing this
>>> differently?
>>
>>
>> The name "prices" is defined and then used, but enjoys no further reference.
>>
>> What happens (from PyLint's PoV) if you make the two lines into one?
>> (overly-complicated and ugly though it would be)
> 
> Strangely, it makes no difference, same warning.


After fileparse, what is type( prices )?
-- 
Regards =dn

From robertvstepp at gmail.com  Sun Jun  7 00:15:03 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 6 Jun 2020 23:15:03 -0500
Subject: [Tutor] Unnecessary comprehension warning
In-Reply-To: <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info>
References: <20200607021947.GB10604@Dream-Machine1>
 <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>
 <CANDiX9KByxor4+7VWBbij1HcregFsYjGTD3aTDZOgYH8rrbMzw@mail.gmail.com>
 <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info>
Message-ID: <CANDiX9+K3FQ1jakvzgPr38V8ivhu_OzE8M+s63ikiyTymWNGpg@mail.gmail.com>

On Sat, Jun 6, 2020 at 10:14 PM DL Neil via Tutor <tutor at python.org> wrote:
>
> On 7/06/20 3:00 PM, boB Stepp wrote:
> > On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor <tutor at python.org> wrote:
> >>
> >> On 7/06/20 2:19 PM, boB Stepp wrote:
> >>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
> >>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html.
> >>>
> >>>
> >>> I rewrote another function in report.py, read_prices(), to make use of the
> >>> parse_csv() function in the fileparse module.  The rewritten function is:
> >>>
> >>> def read_prices(filename: str) -> Dict[str, float]:
> >>>       """Read a file of stock prices and load them into a dictionary."""
> >>>       prices = fileparse.parse_csv(filename, types=[str, float],
> >>> has_headers=False)
> >>>       stock_prices = {stock_name: stock_price for stock_name, stock_price
> >>> in prices}
> >>>       return stock_prices
> >>>
> >>> pylint complains with:
> >>>
> >>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use
> >>> of a comprehension
> >>>
> >>> The dictionary comprehension I'm now using replaces a lengthier for loop
> >>> with indexing instead of nice names.  Am I truly doing things in a bad
> >>> Python style as the linter is complaining?  Should I be doing this
> >>> differently?
> >>
> >>
> >> The name "prices" is defined and then used, but enjoys no further reference.
> >>
> >> What happens (from PyLint's PoV) if you make the two lines into one?
> >> (overly-complicated and ugly though it would be)
> >
> > Strangely, it makes no difference, same warning.
>
>
> After fileparse, what is type( prices )?

type(prices) = <class 'list'>


-- 
boB

From robertvstepp at gmail.com  Sun Jun  7 01:24:35 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 7 Jun 2020 00:24:35 -0500
Subject: [Tutor] Unnecessary comprehension warning
In-Reply-To: <CANDiX9+K3FQ1jakvzgPr38V8ivhu_OzE8M+s63ikiyTymWNGpg@mail.gmail.com>
References: <20200607021947.GB10604@Dream-Machine1>
 <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info>
 <CANDiX9KByxor4+7VWBbij1HcregFsYjGTD3aTDZOgYH8rrbMzw@mail.gmail.com>
 <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info>
 <CANDiX9+K3FQ1jakvzgPr38V8ivhu_OzE8M+s63ikiyTymWNGpg@mail.gmail.com>
Message-ID: <CANDiX9L-Db4-=ssWX8L_ogh1qC9Hcy3GU=R9Spx89Py6ZZHT8Q@mail.gmail.com>

On Sat, Jun 6, 2020 at 11:15 PM boB Stepp <robertvstepp at gmail.com> wrote:
>
> On Sat, Jun 6, 2020 at 10:14 PM DL Neil via Tutor <tutor at python.org> wrote:
> >
> > On 7/06/20 3:00 PM, boB Stepp wrote:
> > > On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor <tutor at python.org> wrote:
> > >>
> > >> On 7/06/20 2:19 PM, boB Stepp wrote:
> > >>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at
> > >>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html.
> > >>>
> > >>>
> > >>> I rewrote another function in report.py, read_prices(), to make use of the
> > >>> parse_csv() function in the fileparse module.  The rewritten function is:
> > >>>
> > >>> def read_prices(filename: str) -> Dict[str, float]:
> > >>>       """Read a file of stock prices and load them into a dictionary."""
> > >>>       prices = fileparse.parse_csv(filename, types=[str, float],
> > >>> has_headers=False)
> > >>>       stock_prices = {stock_name: stock_price for stock_name, stock_price
> > >>> in prices}
> > >>>       return stock_prices
> > >>>
> > >>> pylint complains with:
> > >>>
> > >>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use
> > >>> of a comprehension
> > >>>
> > >>> The dictionary comprehension I'm now using replaces a lengthier for loop
> > >>> with indexing instead of nice names.  Am I truly doing things in a bad
> > >>> Python style as the linter is complaining?  Should I be doing this
> > >>> differently?

Finally figured it out.  The linter was correct!  I should just return
the following:

return dict(fileparse.parse_csv(fileobj, types=[str, float], has_headers=False))

Doh!

-- 
boB

From jf_byrnes at comcast.net  Sat Jun  6 23:44:05 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 6 Jun 2020 22:44:05 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <rbgnu0$29ac$1@ciao.gmane.io>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
Message-ID: <rbhnq5$3hv4$1@ciao.gmane.io>

On 6/6/20 1:39 PM, Peter Otten wrote:

Peter,

I see that my original message never showed up so I am re-sending it.

 > Jim wrote:
 >
 >> On 6/6/20 4:25 AM, Peter Otten wrote:
 >>> Jim wrote:
 >>>
 >>>> Mint18.3, python3.6, pandas 0.24.1
 >>>>
 >>>>
 >>>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv'
 >>>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6,
 >>>> engine='python')
 >>>> df.to_clipboard(sep=',')
 >>>> print(df)
 >>>>
 >>>> Manual notes the following. I'm not using PyQt4, but xclip is 
installed.
 >>>>
 >>>> Notes: Requirements for your platform.
 >>>>
 >>>>        Linux : xclip, or xsel (with PyQt4 modules)
 >>>>        Windows : none
 >>>>        OS X : none
 >>>>
 >>>> The print command prints what I expect to see.
 >>>>
 >>>> I don't use pandas that much so maybe I am missing something.
 >>>
 >>> The pandas side seems OK; maybe you are looking at the wrong selection?
 >>> I have a slightly different setup, and the following works for me:
 >>>
 >>> $ python3
 >>> Python 3.4.3 (default, Nov 12 2018, 22:25:49)
 >>> [GCC 4.8.4] on linux
 >>> Type "help", "copyright", "credits" or "license" for more information.
 >>>>>> import pandas
 >>>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"])
 >>>>>> df.to_clipboard(sep=", ")
 >>>>>>
 >>> $ xclip -o -selection clipboard
 >>>      Ham  Spam
 >>> 0    1     2
 >>> 1    3     4$
 >>>
 >>
 >> Peter,
 >>
 >> I'm not sure what you mean by the "wrong selection" above. I ran your
 >> code and got the following results.
 >>
 >>
 >> This version (space after ,) worked despite the error msg:
 >>
 >> Python 3.6.10 (default, Dec 19 2019, 23:04:32)
 >> [GCC 5.4.0 20160609] on linux
 >> Type "help", "copyright", "credits" or "license" for more information.
 >>   >>> import pandas
 >>   >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"])
 >>   >>> df.to_clipboard(sep=", ")
 >> QApplication: invalid style override passed, ignoring it.
 >>       Available styles: Windows, Fusion
 >> 
/home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134:
 >> UserWarning: to_clipboard in excel mode requires a single character
 >> separator.
 >>     warnings.warn('to_clipboard in excel mode requires a single '
 >>
 >> Copied from clipboard:
 >>      Ham  Spam
 >> 0    1     2
 >> 1    3     3
 >>
 >> This version (no space after ,) also worked despite a different 
error msg:
 >>
 >> (env36) jfb at jims-mint18 ~ $ python
 >> Python 3.6.10 (default, Dec 19 2019, 23:04:32)
 >> [GCC 5.4.0 20160609] on linux
 >> Type "help", "copyright", "credits" or "license" for more information.
 >>   >>> import pandas
 >>   >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"])
 >>   >>> df.to_clipboard(sep=",")
 >> QApplication: invalid style override passed, ignoring it.
 >>       Available styles: Windows, Fusion
 >>
 >> Copied from clipboard:
 >> ,Ham,Spam
 >> 0,1,2
 >> 1,3,4
 >>
 >>
 >> I had a little test file I was using to figure out pandas so I dropped
 >> your code in it. Nothing was copied to the clipboard and this is the
 >> error msg:
 >>
 >> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
 >> QApplication: invalid style override passed, ignoring it.
 >>       Available styles: Windows, Fusion
 >> 
/home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134:
 >> UserWarning: to_clipboard in excel mode requires a single character
 >> separator.
 >>     warnings.warn('to_clipboard in excel mode requires a single '
 >>
 >> So I added excel=False and dropped the sep= and got this error:
 >>
 >> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
 >> QApplication: invalid style override passed, ignoring it.
 >>       Available styles: Windows, Fusion
 >>
 >> I don't understand the QApplication reference. I assume it refers to QT
 >> I have some QT stuff installed:
 >>
 >> from pip list:
 >> PyQt5                    5.12
 >> PyQt5-sip                4.19.14
 >> qtconsole                4.4.3
 >>
 >> I don't know why QT would come into play here and I don't understand the
 >> reference to excel when it was not included.
 >>
 >> To sum up. If I run it from the python console it give an error, but
 >> copies to the clipboard. If I run the python file from the terminal it
 >> gives an error and does not copy to the clipboard.
 >
 > Most of your errors seem to be warnings.
 >
 > Looking into the code writing to the clipboard shows that it requires the
 > DISPLAY environment variable to be set, so I'd check that in the 
terminal.
 >
 > 
https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539
 >
 > shows that
 >
 >      if HAS_DISPLAY:
 >          if _executable_exists("xsel"):
 >              return init_xsel_clipboard()
 >          if _executable_exists("xclip"):
 >              return init_xclip_clipboard()
 >          if _executable_exists("klipper") and 
_executable_exists("qdbus"):
 >              return init_klipper_clipboard()
 >          ... [try qt]
 >
 > QT is the last option. From that we can conclude that xclip is not found.
 > Maybe you can fix that by adjusting the path.
 > Or you try to set the clipboard mechanism explicitly with
 >
 > pandas.io.clipboard.set_clipboard("xclip")
 >

Well I have it working. I have a VE with python 3.5 in it, no QT 
installed. I ran the test script and it copied the info to the clipboard.

I went back to the VE with 3.6 and upgraded PyQt5 & PyQt5-sip. I ran the 
test script and it gave a Qt error basically saying it could not load a 
plugin even though it was installed. At that point I uninstalled the Qt 
stuff from the 3.6 VE and the script copied the dataframe to the 
clipboard. Then I tried your xclip command.

  xclip -o -selection clipboard
,Ham,Spam
0,1,2
1,3,4

Here is the output of items containing QT or DISPLAY from printenv:

QT_STYLE_OVERRIDE=
QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1
QT_ACCESSIBILITY=1
QT_QPA_PLATFORMTHEME=qgnomeplatform
QT4_IM_MODULE=xim
DISPLAY=:0

You certainly know more about this than I do, but I wonder about the 
conclusion that xclip is not found. In VE 3.5 and now VE 3.6 there is no 
QT to fall back on but the script worked and xclip worked after the 
script ran. I don't know what DISPLAY should equal.

I don't think I need QT any more so I am going to stop trying to figure 
this out and try to finish the script I was working on. I do plan on 
coming back and see if there is a different solution other than deleting 
PyQt5.

I do want to thank you for all the help you have given me in this matter.

Regards,  Jim


From manpritsinghece at gmail.com  Sun Jun  7 01:48:41 2020
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Sun, 7 Jun 2020 11:18:41 +0530
Subject: [Tutor] Fwd: Question regarding use of assignment expression in
 python 3.8.3
In-Reply-To: <CAO1OCwY9yKzemAC6RB=iT9+081CxUuTEVG9AF20=YqBCwCK+AQ@mail.gmail.com>
References: <CAO1OCwY9yKzemAC6RB=iT9+081CxUuTEVG9AF20=YqBCwCK+AQ@mail.gmail.com>
Message-ID: <CAO1OCwYfAes8CiWNNWVcyVPbgCPZMokFNwQ21-ZEiJt-ML0+pg@mail.gmail.com>

Dear All,

According to Heron's formula for finding area of a triangle , if the sides
of a triangle  are a, b & c is :
area =sqrt( s * (s-a) * (s-b) * (s-c))    # sqrt means square root
where s = (a+b+c) / 2

so for finding the area of the triangle using Heron's formula in Python ,
if i write code like this , will it be a valid practise ?
I have used assignment expression while calculating the  area

a = int(input("Enter value of first side"))                     # Assuming
value is integer
b = int(input("Enter value of second side"))               # Assuming value
is integer
c = int(input("Enter value of third side"))                    # Assuming
value is integer
area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5
print("Area of the triangle is", area)

Regards
Manprit Singh



---------- Forwarded message ---------
From: Manprit Singh <manpritsinghece at gmail.com>
Date: Sat, Jun 6, 2020 at 11:59 PM
Subject: Question regarding use of assignment expression in python 3.8.3
To: <tutor at python.org>


Dear all,

According to Heron's formula for finding area of a triangle , if the sides
of a triangle  are a, b & c is :
area =sqrt( s * (s-a) * (s-b) * (s-c))    # sqrt means square root
where s = (a+b+c) / 2

so for finding the area of the triangle using Heron's formula in Python ,
if i write code like this , will it be a valid practise ?
I have used assignment expression while calculating the  area

a = int(input("Enter value of first side"))                     # Assuming
value is integer
b = int(input("Enter value of second side"))               # Assuming value
is integer
c = int(input("Enter value of third side"))                    # Assuming
value is integer
area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5
print("Area of the triangle is", area)

Regards
Manprit Singh

From __peter__ at web.de  Sun Jun  7 05:07:34 2020
From: __peter__ at web.de (Peter Otten)
Date: Sun, 07 Jun 2020 11:07:34 +0200
Subject: [Tutor] pandas.to_clipboard() copies nothing
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
 <rbhnq5$3hv4$1@ciao.gmane.io>
Message-ID: <rbiaon$3e78$1@ciao.gmane.io>

Jim wrote:

> You certainly know more about this than I do, but I wonder about the
> conclusion that xclip is not found. 

I don't know much, "qt tried as last resort" is my interpretation of the 
latest pandas code, without actually running it.

> I don't think I need QT any more so I am going to stop trying to figure
> this out and try to finish the script I was working on. I do plan on
> coming back and see if there is a different solution other than deleting
> PyQt5.

Did you try invoking

pandas.io.clipboard.set_clipboard("xclip")

before pasting?

> I do want to thank you for all the help you have given me in this matter.

You're welcome.


From alan.gauld at yahoo.co.uk  Sun Jun  7 07:10:32 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 7 Jun 2020 12:10:32 +0100
Subject: [Tutor] Fwd: Question regarding use of assignment expression in
 python 3.8.3
In-Reply-To: <CAO1OCwYfAes8CiWNNWVcyVPbgCPZMokFNwQ21-ZEiJt-ML0+pg@mail.gmail.com>
References: <CAO1OCwY9yKzemAC6RB=iT9+081CxUuTEVG9AF20=YqBCwCK+AQ@mail.gmail.com>
 <CAO1OCwYfAes8CiWNNWVcyVPbgCPZMokFNwQ21-ZEiJt-ML0+pg@mail.gmail.com>
Message-ID: <rbihv8$2l2i$1@ciao.gmane.io>

On 07/06/2020 06:48, Manprit Singh wrote:

This appears to be a duplicate posting from a few days ago,
so I'll send you the duplicate answer! :-)


> so for finding the area of the triangle using Heron's formula in Python ,
> if i write code like this , will it be a valid practise ?


Yes, if you just want to practice use of assignment expressions.

> area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5

Its syntactically valid to use it here but offers very no
advantage over a separate assignment line

s = a+b+c

And has 2 minor disadvantages:
1) its more typing (2 keystrokes)
2) its harder to debug - no way to inspect s prior to executing
   the calculation.


-- 
-- 
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 bouncingcats at gmail.com  Sun Jun  7 08:51:07 2020
From: bouncingcats at gmail.com (David)
Date: Sun, 7 Jun 2020 22:51:07 +1000
Subject: [Tutor] Beginner Noob
In-Reply-To: <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
 <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
Message-ID: <CAMPXz=qNcD+rQGP+BFNxFKgTZYOxjjSO+owY5W-e7ZUPV4ihQQ@mail.gmail.com>

On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor <tutor at python.org> wrote:

> There is a MicroPython which works well on Raspberry Pi SBCs, whereas
> there is a version of C which is native to the Arduino.

May I offer a small correction, because this seems a bit misleading about
the MicroPython project [1]. The whole point of MicroPython is that it
has been designed to run directly on a tiny microcontroller, with no
operating system required, and is optimised for doing so at the cost
of other performance aspects. It can also run on Linux, for development.

Raspberry Pi runs Linux. So although you *can* run MicroPython on a
Raspberry Pi, you generally wouldn't, because there's no point, and
any of the other Linux varieties of Python will probably perform better,
generally speaking, because they will exploit all the advantages provided
by the operating system.

[1] https://micropython.org/

From alexkleider at protonmail.com  Sun Jun  7 12:58:36 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Sun, 07 Jun 2020 16:58:36 +0000
Subject: [Tutor] Beginner Noob
In-Reply-To: <CAMPXz=qNcD+rQGP+BFNxFKgTZYOxjjSO+owY5W-e7ZUPV4ihQQ@mail.gmail.com>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
 <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
 <CAMPXz=qNcD+rQGP+BFNxFKgTZYOxjjSO+owY5W-e7ZUPV4ihQQ@mail.gmail.com>
Message-ID: <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com>

??????? Original Message ???????
On Sunday, June 7, 2020 5:51 AM, David <bouncingcats at gmail.com> wrote:

> On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor tutor at python.org wrote:
>
> > There is a MicroPython which works well on Raspberry Pi SBCs, whereas
> > there is a version of C which is native to the Arduino.
>
> May I offer a small correction, because this seems a bit misleading about
> the MicroPython project [1]. The whole point of MicroPython is that it
> has been designed to run directly on a tiny microcontroller, with no
> operating system required, and is optimised for doing so at the cost
> of other performance aspects. It can also run on Linux, for development.
>
> Raspberry Pi runs Linux. So although you can run MicroPython on a
> Raspberry Pi, you generally wouldn't, because there's no point, and
> any of the other Linux varieties of Python will probably perform better,
> generally speaking, because they will exploit all the advantages provided
> by the operating system.
>
> [1] https://micropython.org/

A few comments that might be pertinent (from another grey head _without_ a tech background.)

There was a tutorial given at the San Francisco Python MeetUp group at what may have been the last meeting they had before the lock-down.
It was about microPython on the arduino.  You might wish to look that up- there may be info related to it on line.  I can try to look up contacts who might be helpful if you wish.
I've used the RPi a lot- it is very Python orientated and I doubt that you'd run into difficulties because of limited resources, especially if you got a late model one- each model has more ports, more memory, faster processor, ...
It's easy to run the Pi 'headless' so no need for setting up monitor, keyboard, mouse etc (as long as you are comfortable with SSH and the terminal command line.)
Be happy to discuss further (on or off list, the latter perhaps being more appropriate since it will be mostly about the Pi rather than Python.)
Cheers,
Alex



From robertvstepp at gmail.com  Sun Jun  7 13:51:33 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 7 Jun 2020 12:51:33 -0500
Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object"
 in class statements?
Message-ID: <20200607175133.GC10604@Dream-Machine1>

Now in "4.1 Classes" at
https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html.

Basic question for Python 3 only development:  Is it better style to use
"class ClassName:" or "class ClassName(object):"?  Beazley uses the former
in this material (so far).  Other readings online (no citations handy)
prefer being explicit with the latter.  I note that pylint prefers omitting
"(object)", calling it "useless-object-inheritance".

I realize that if I am trying to write code compatible with both Python 2
and 3 that I need to explicitly inherit from "object".

So, for Python 3 only development is there any consensus?  Are there any
real arguments for being "explicit" with inheriting from "object"?  I have
to say that I have not yet found the allusion to Zen to be explicit not
convincing.

-- 
Wishing you only the best,

boB Stepp

From mats at wichmann.us  Sun Jun  7 14:15:03 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 7 Jun 2020 12:15:03 -0600
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <20200607175133.GC10604@Dream-Machine1>
References: <20200607175133.GC10604@Dream-Machine1>
Message-ID: <a11497b4-29fa-d6b9-9934-f2d0763d67ef@wichmann.us>

On 6/7/20 11:51 AM, boB Stepp wrote:
> Now in "4.1 Classes" at
> https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html.
> 
> 
> Basic question for Python 3 only development:? Is it better style to use
> "class ClassName:" or "class ClassName(object):"?? Beazley uses the former
> in this material (so far).? Other readings online (no citations handy)
> prefer being explicit with the latter.? I note that pylint prefers omitting
> "(object)", calling it "useless-object-inheritance".
> 
> I realize that if I am trying to write code compatible with both Python 2
> and 3 that I need to explicitly inherit from "object".
> 
> So, for Python 3 only development is there any consensus?? Are there any
> real arguments for being "explicit" with inheriting from "object"?? I have
> to say that I have not yet found the allusion to Zen to be explicit not
> convincing.

Consensus? Hah!

It seems kind of odd to need to supply something that is a guaranteed
language feature:

>>> class Spam:
...     pass
...
>>> Spam.__mro__
(<class '__main__.Spam'>, <class 'object'>)
>>>


But then, there can't be any confusion if you're explicit, and if you're
writing code which might be considered for use in Python 2, then it's
easier to keep it.


I don't use (object), and recently submitted patches to a 20-year old
project that has recently become Python3-only to drop them, which the
maintainer accepted.


Here's my claim:  listen to pylint, or someday you'll end up having to
defend why you're doing something pylint complains about.  :)   Tools
like Pylint and Black are pretty opinionated (although Black is so
opinionated that you can't override most of its choices, while Pylint is
almost infintely configurable), and sometimes it's just easier to go
with the flow.



From Richard at Damon-Family.org  Sun Jun  7 15:35:39 2020
From: Richard at Damon-Family.org (Richard Damon)
Date: Sun, 7 Jun 2020 15:35:39 -0400
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <20200607175133.GC10604@Dream-Machine1>
References: <20200607175133.GC10604@Dream-Machine1>
Message-ID: <fa012352-e10e-d62b-5273-75ebc662b50d@Damon-Family.org>

On 6/7/20 1:51 PM, boB Stepp wrote:
> Now in "4.1 Classes" at
> https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html.
>
>
> Basic question for Python 3 only development:? Is it better style to use
> "class ClassName:" or "class ClassName(object):"?? Beazley uses the
> former
> in this material (so far).? Other readings online (no citations handy)
> prefer being explicit with the latter.? I note that pylint prefers
> omitting
> "(object)", calling it "useless-object-inheritance".
>
> I realize that if I am trying to write code compatible with both Python 2
> and 3 that I need to explicitly inherit from "object".
>
> So, for Python 3 only development is there any consensus?? Are there any
> real arguments for being "explicit" with inheriting from "object"?? I
> have
> to say that I have not yet found the allusion to Zen to be explicit not
> convincing.
>
As you note, the (object) was needed in Python2 to make it a "New Style"
class, while in Python 3 that is the only style class that exists.

In Python3, it is purely optional, and its presence is merely stylistic.
The big question comes, are you working on a project or with a group of
programmers used to dealing with Python2, so have the habit of the
explicit reference to object, or is the project brand new with fresh
developers, for whom the (object) would be just noise?

I suspect that most new projects will actually fall somewhat in the
middle, not needing to be compatible with Python 2 (let it rest in
peace) but with some developers still with older habits, and a decision
needing to be made as to which style is more readable TO THAT TEAM.

There of course are also 'zealots' who are frustrated by the extremely
slow demise of Python 2 and want to purge its memory from the style and
therefore want to insist on dropping the now unneeded (object) from the
definition, being afraid of Python 2 saying "I'm not dead yet", and
wanting to try to hammer the nails in the coffin to be rid of it.

-- 
Richard Damon


From PyTutor at DancesWithMice.info  Sun Jun  7 16:08:33 2020
From: PyTutor at DancesWithMice.info (DL Neil)
Date: Mon, 8 Jun 2020 08:08:33 +1200
Subject: [Tutor] Beginner Noob
In-Reply-To: <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
 <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
 <CAMPXz=qNcD+rQGP+BFNxFKgTZYOxjjSO+owY5W-e7ZUPV4ihQQ@mail.gmail.com>
 <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com>
Message-ID: <b34bb15e-7ae9-6b54-c78a-2ac0e1ad7277@DancesWithMice.info>

On 8/06/20 4:58 AM, alexkleider via Tutor wrote:
> ??????? Original Message ???????
> On Sunday, June 7, 2020 5:51 AM, David <bouncingcats at gmail.com> wrote:
> 
>> On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor tutor at python.org wrote:
>>
>>> There is a MicroPython which works well on Raspberry Pi SBCs, whereas
>>> there is a version of C which is native to the Arduino.
>>
>> May I offer a small correction, because this seems a bit misleading about
>> the MicroPython project [1]. The whole point of MicroPython is that it
>> has been designed to run directly on a tiny microcontroller, with no
>> operating system required, and is optimised for doing so at the cost
>> of other performance aspects. It can also run on Linux, for development.
>>
>> Raspberry Pi runs Linux. So although you can run MicroPython on a
>> Raspberry Pi, you generally wouldn't, because there's no point, and
>> any of the other Linux varieties of Python will probably perform better,
>> generally speaking, because they will exploit all the advantages provided
>> by the operating system.
>>
>> [1] https://micropython.org/
> 
> A few comments that might be pertinent (from another grey head _without_ a tech background.)
> 
> There was a tutorial given at the San Francisco Python MeetUp group at what may have been the last meeting they had before the lock-down.
> It was about microPython on the arduino.  You might wish to look that up- there may be info related to it on line.  I can try to look up contacts who might be helpful if you wish.
> I've used the RPi a lot- it is very Python orientated and I doubt that you'd run into difficulties because of limited resources, especially if you got a late model one- each model has more ports, more memory, faster processor, ...
> It's easy to run the Pi 'headless' so no need for setting up monitor, keyboard, mouse etc (as long as you are comfortable with SSH and the terminal command line.)
> Be happy to discuss further (on or off list, the latter perhaps being more appropriate since it will be mostly about the Pi rather than Python.)


Thanks both!

Yes, I had taken a language-centric approach to advising the OP. Of 
course, were I paid, I might say "only Python, everywhere"...

For this reason and the helpful added detail, eg SSH/'headless', IMHO 
stay *on-list*, for now. If the microPython/SBC traffic increases to the 
point of 'irritation', it will demonstrate demand and thereby justify a 
separate list, eg Python on SBCs.

That said, there are other sources for such information and discussion.


PS I'm formulating another in my "Friday Finking" philosophical 
discussions (on the 'main' Python list) which will hark-back to playing 
with 4-bit processors during the '70s, and hopes-and-dreams perhaps lost 
or misplaced mean-time...
-- 
Regards =dn

From alan.gauld at yahoo.co.uk  Sun Jun  7 16:36:34 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 7 Jun 2020 21:36:34 +0100
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <20200607175133.GC10604@Dream-Machine1>
References: <20200607175133.GC10604@Dream-Machine1>
Message-ID: <rbjj4i$1rjb$1@ciao.gmane.io>

On 07/06/2020 18:51, boB Stepp wrote:

> So, for Python 3 only development is there any consensus?  Are there any
> real arguments for being "explicit" with inheriting from "object"?  

No idea, but I never use object these days.
I stopped using Pyhon 2.7 for anything (other than answering other
peoples questions) about 2 years ago...


-- 
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 Jun  7 16:37:04 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 7 Jun 2020 15:37:04 -0500
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <a11497b4-29fa-d6b9-9934-f2d0763d67ef@wichmann.us>
References: <20200607175133.GC10604@Dream-Machine1>
 <a11497b4-29fa-d6b9-9934-f2d0763d67ef@wichmann.us>
Message-ID: <20200607203704.GD10604@Dream-Machine1>

On Sun, Jun 07, 2020 at 12:15:03PM -0600, Mats Wichmann wrote:

>Here's my claim:  listen to pylint, or someday you'll end up having to
>defend why you're doing something pylint complains about.  :)   Tools
>like Pylint and Black are pretty opinionated (although Black is so
>opinionated that you can't override most of its choices, while Pylint is
>almost infintely configurable), and sometimes it's just easier to go
>with the flow.

As you are obviously remembering, I have recently started "playing" with
Black and Pylint.  Black I don't even try to fight while I am using it as, I
probably cannot change its behavior -- the whole point of using it, really.
But Pylint, which has so many possibilities for customization, has
generated a real reluctance on my part to "tweak" it:

     1) I generally don't feel confident that I have enough knowledge and
        background to make the tweaks without either asking on this forum
        first and/or doing online research.
     2) In line with (1) it *has* caught misconceptions on my part even
        though (at the time) I was *certain* that it was a silly complaint.
        See, for instance, my post last night about an unneeded comprehension.
        I had forgotten which data file format I was currently dealing
        with and did not realize I could use dict() directly, something
        that, I am sure, never happens to you pros.  ~(:>))
     3) And it has been quite useful in finding things I had absolutely no
        clue about and needed to look up and learn.
     4) *If* I *do* reach the "full confidence" level to make a tweak then I
        have to give careful consideration as to whether I want to make the tweak
        applicable to all of my projects -- past, present and future -- or
        if I want to make it more narrowly applicable.  This creates a certain
        reluctance when it is usually quicker to just change the code.  A
        good example of this would be something like "with open(filename) as
        f".  There will surely follow a complaint about the single letter
        variable even though I don't think it will cause any future person
        misunderstanding.
     5) So your comment "...and sometimes it's just easier to go with the
        flow" seems to dominate for me.

All in all though I believe Pylint and company are proving (on balance)
helpful to my learning and preventing mistakes.

-- 
Wishing you only the best,

boB Stepp

From jf_byrnes at comcast.net  Sun Jun  7 10:38:34 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sun, 7 Jun 2020 09:38:34 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <rbiaon$3e78$1@ciao.gmane.io>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
 <rbhnq5$3hv4$1@ciao.gmane.io> <rbiaon$3e78$1@ciao.gmane.io>
Message-ID: <rbiu5c$pbg$1@ciao.gmane.io>

On 6/7/20 4:07 AM, Peter Otten wrote:
> Jim wrote:
> 
>> You certainly know more about this than I do, but I wonder about the
>> conclusion that xclip is not found.
> 
> I don't know much, "qt tried as last resort" is my interpretation of the
> latest pandas code, without actually running it.



>> I don't think I need QT any more so I am going to stop trying to figure
>> this out and try to finish the script I was working on. I do plan on
>> coming back and see if there is a different solution other than deleting
>> PyQt5.
> 
> Did you try invoking
> 
> pandas.io.clipboard.set_clipboard("xclip")
> 
> before pasting?

No unfortunately I did not. I wanted to get back to working on the 
script that exposed this mess so when deleting the QT stuff worked I 
just moved on. Once I get that script running I plan on re-installing QT 
and see what happens.



Regards,  Jim


From alan.gauld at yahoo.co.uk  Sun Jun  7 16:41:42 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 7 Jun 2020 21:41:42 +0100
Subject: [Tutor] Beginner Noob
In-Reply-To: <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
 <e1ccbc87-4584-e477-cdfa-516a374ef9a0@DancesWithMice.info>
Message-ID: <rbjje6$2v5k$1@ciao.gmane.io>

I thought I'd already sent this but it doesn't appear to have arrived...

On 06/06/2020 09:38, DL Neil via Tutor wrote:

> There is a MicroPython which works well on Raspberry Pi SBCs, whereas 
> there is a version of C which is native to the Arduino.

Off topic but I'm curious about a native C for Arduino.
The basic development IDE for Arduino comes with a C++ compiler.
What is the "native C" and why would anyone use it given
that C++ is almost a complete superset of C?

What is the advantage?

-- 
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 PyTutor at danceswithmice.info  Sun Jun  7 16:51:05 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Mon, 8 Jun 2020 08:51:05 +1200
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <fa012352-e10e-d62b-5273-75ebc662b50d@Damon-Family.org>
References: <20200607175133.GC10604@Dream-Machine1>
 <fa012352-e10e-d62b-5273-75ebc662b50d@Damon-Family.org>
Message-ID: <dc4ac244-d10a-8982-2bad-707df949f9a9@DancesWithMice.info>

On 8/06/20 7:35 AM, Richard Damon wrote:
> On 6/7/20 1:51 PM, boB Stepp wrote:
>> Now in "4.1 Classes" at
>> https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html.
>>
>>
>> Basic question for Python 3 only development:? Is it better style to use
>> "class ClassName:" or "class ClassName(object):"?? Beazley uses the
>> former
>> in this material (so far).? Other readings online (no citations handy)
>> prefer being explicit with the latter.? I note that pylint prefers
>> omitting
>> "(object)", calling it "useless-object-inheritance".
>>
>> I realize that if I am trying to write code compatible with both Python 2
>> and 3 that I need to explicitly inherit from "object".
>>
>> So, for Python 3 only development is there any consensus?? Are there any
>> real arguments for being "explicit" with inheriting from "object"?? I
>> have
>> to say that I have not yet found the allusion to Zen to be explicit not
>> convincing.
>>
> As you note, the (object) was needed in Python2 to make it a "New Style"
> class, while in Python 3 that is the only style class that exists.
> 
> In Python3, it is purely optional, and its presence is merely stylistic.
> The big question comes, are you working on a project or with a group of
> programmers used to dealing with Python2, so have the habit of the
> explicit reference to object, or is the project brand new with fresh
> developers, for whom the (object) would be just noise?
> 
> I suspect that most new projects will actually fall somewhat in the
> middle, not needing to be compatible with Python 2 (let it rest in
> peace) but with some developers still with older habits, and a decision
> needing to be made as to which style is more readable TO THAT TEAM.
> 
> There of course are also 'zealots' who are frustrated by the extremely
> slow demise of Python 2 and want to purge its memory from the style and
> therefore want to insist on dropping the now unneeded (object) from the
> definition, being afraid of Python 2 saying "I'm not dead yet", and
> wanting to try to hammer the nails in the coffin to be rid of it.


I enjoy being made to step-back and think...

I'm about as far from being a 'zealot' for lint-ing as one can get, but 
have a keen appreciation for the psychology of consistency (both amongst 
a team and 'within' an individual - without that, lies madness!)

These days I'm exclusively using Python3 and think that all 
active-clients and their project have been upgraded - but that from 
'common sense' rather than any agenda to 'kill' Python2.


Having come from those days (when men were men, knights were bold, ...) 
my 'muscle-memory' adds parentheses when defining ClassNames (ie without 
conscious thought).

I have learned not to add "object" between (he's 'slow', but usually he 
gets 'there'!).

However, there is still some vestige of recognition in my mind, that the 
parentheses 'make' it a class (wrong!) - or make it easier to recognise 
the code-line as-such (which assumes reading-mode cf asking one's IDE to 
locate/display the class definition).

 From the other perspective, a sub-class *must* use a parenthetical 
expression:

     class LinksRegister( collections.UserList ):

cf

     class LinksRegister():	# being consistent!?
     class LinksRegister:	# being precise!?

Hence the unadorned option, whilst 'the most correct', looks slightly 
odd (to me). Cue: gather around and sing "Tradition"*

Pycharm (in as much as it embodies PEPs, linters, and style) whilst 
typing a new class definition offers "':' expected". If empty 
parentheses are added, it then instructs "Remove redundant parentheses".

Does a touch-typist (a real man, a knight, ...) even notice these 
messages? Nah!
(Woe is me...)


* Fiddler on the Roof https://www.imdb.com/title/tt0067093/?ref_=fn_al_tt_1
-- 
Regards =dn

From 1611kjb at gmail.com  Sun Jun  7 17:54:32 2020
From: 1611kjb at gmail.com (Michael Deslippe)
Date: Sun, 7 Jun 2020 21:54:32 +0000
Subject: [Tutor] Beginner Noob
In-Reply-To: <rbfic0$2l5b$1@ciao.gmane.io>
References: <023d01d63b98$22f22290$68d667b0$@gmail.com>
 <rbfic0$2l5b$1@ciao.gmane.io>
Message-ID: <034701d63c3b$495c96b0$dc15c410$@Domain>

Thank you very much for the input. Somewhere around 5-10 years ago
Microsoft was deciding whether to retain VB or drop support all together.
After much debate they decided VB could be as structured and modern as any
language and that they were going to move in that direction. I had moved
away from programming by then and never followed what has happened with
the language. I remember Microsoft's first foray into improving BASIC when
they introduced Qbasic. It was well received (I still have the components
for it) but it wasn't much of an evolutionary leap, however it helped the
average MS-DOS and early Windows user deal with quick programming.

Sounds like I may jump on the Python bandwagon and slow my work on C# until I need it, or I have gone the distance with Python. I don?t believe anyone ever masters an active evolving language, but I believe their are users and there are inventors. I user learns enough to become proficient in solving problems in other environments requiring programming, an inventor is always looking for better ways to use the tool and rewrite code they?ve already written to make it the best they can. I?m the former. I?ve been the latter in other stages of my growth, but now most things have me living with practicality.

Thanks for the input, it?s been helpful.

?-Mike

-----Original Message-----
From: Tutor <tutor-bounces+1611kjb=gmail.com at python.org> On Behalf Of Alan
Gauld via Tutor
Sent: Saturday, June 6, 2020 3:59 AM
To: tutor at python.org
Subject: Re: [Tutor] Beginner Noob

On 06/06/2020 01:19, 1611kjb at gmail.com wrote:

> Whew, I'm long winded, I say all that to ask, what are the advantages
> to jumping over to Python from VB?

Python is a more modern language with more powerful data structures and
language constructs. Although with modern VB.Net that's less of an
argument. Python also has an awesome standard library and third-party
supported ecosystem.

> I am simultaneously working on C# and
> wondering if it's worth taxing myself to learn another language.

Every language teaches lessons that you can apply in every other language.
Some teach more than others - Lisp, Smalltalk, Prolog, etc

C# is a traditional language in the same vein as C/C++/Pascal/Java.
It's very good for large projects (100k+ lines) involving many
programmers. But it requires a lot of planning and design at a detailed
level to use effectively.

Python is designed for rapid implementation. It's not as fast in execution
but it can be thrown together in a more experimental fashion. Before I
retired I used Python as a prototyping language before handing designs
over to our contractor programmers who were using Java. Of course Python
can be used in production code too with a little extra care.

VB sits somewhere between those two on the technology continuum Faster to
write than C#, not as fast as Python(unless you are building GUIs) but not
as powerful as C# either. (I may be wrong but I get the impression that
VB.Net is slowly fading away.
C# has closed the gap to the point where VB's advantages have been
eroded.)


> platform for K12 education, Arduino controllers and Raspberry PI
computers.
> They all seem to like Python and C, C++ and C#. I'm an old retired guy
> stretching the grey muscles and just wondering if this is a good way
> to apply myself. Thanks for any input. I'm sure I'll br here a lot.
Python is used in all these areas and is generally considered easier to
learn than C# and certainly C++. I would only recommend C++ if you are
tinkering at the machine level - its the natural partner for an Arduino
for example. C# (and Java) are similar to C++ but more focused on higher
level application code. C++ compiles to native machine code. All the
others compile to bytecode which is then interpreted. For normal human
interactive programs it makes little difference on modern computers. If
you are writing a high data volume server or a piece of hardware interface
then speed may become an issue and c++ wins. But at the expense of much
harder to write, test and debug code.


--
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 1611kjb at gmail.com  Sun Jun  7 18:16:27 2020
From: 1611kjb at gmail.com (Michael Deslippe)
Date: Sun, 7 Jun 2020 22:16:27 +0000
Subject: [Tutor] =?windows-1252?q?=93Native_C=94?=
Message-ID: <YT1PR01MB30493E6F2B57F25ED793051BA9840@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>

I?m just guessing here, but ?advantage? may be the wrong view. What is it that you call ?Native C?? From my view, before any versions came along, ?C? was the foundation for Unix and came packaged with virtually and distribution), thus development in C became natural as you merely had to reach out and touch it. As versions of Unix developed, C morphed right along with it. Again, I?m an old guy, but last I knew, the winner came out as Linux and Linux wasn?t given  a native copy of C.

Arduino is founded on rudimentary control and so it leans towards rudimentary answers. Arduino doesn?t actually understand all of C but only a subset of the language as that?s all that is necessary. Creating subsets of different versions simply to extract the subset required by Arduino would be a lot of work with no tangible benefit. Raspberry Pi however, uses the full spectrum of C and, as one would expect, has developed all the flavors of C, C++ and C#. However, if you understand the needs of Arduino, you can write programs from any flavor just so long as you and the compiler don?t touch things Arduino doesn?t understand. As I understand it, Arduino big brother, the 2560 Mega understands more than the Uno and I understand they are working on several renditions surpassing the Mega. So we may see broader acceptance of C variants before too long.

---Mike


I thought I'd already sent this but it doesn't appear to have arrived...

On 06/06/2020 09:38, DL Neil via Tutor wrote:

> There is a MicroPython which works well on Raspberry Pi SBCs, whereas
> there is a version of C which is native to the Arduino.

Off topic but I'm curious about a native C for Arduino.
The basic development IDE for Arduino comes with a C++ compiler.
What is the "native C" and why would anyone use it given
that C++ is almost a complete superset of C?

What is the advantage?

--
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<mailto:Tutor at python.org>
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

From robertvstepp at gmail.com  Sun Jun  7 23:02:50 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 7 Jun 2020 22:02:50 -0500
Subject: [Tutor] What are the benefits of template or abstract base classes?
Message-ID: <20200608030250.GF10604@Dream-Machine1>

Now in "4.2 Inheritance" at
https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html

class TableFormatter:
     def headings(self, headers):
         '''
         Emit the table headings.
         '''
	raise NotImplementedError()

     def row(self, rowdata):
         '''
         Emit a single row of table data.
         '''
	raise NotImplementedError()

with the comment:

"This class does nothing, but it serves as a kind of design specification
for additional classes that will be defined shortly. A class like this is
sometimes called an ?abstract base class.?"

As the exercises in this section progressed I had to write the classes
TextTableFormatter(TableFormatter), CSVTableFormatter(TableFormatter) and
HTMLTableFormatter(TableFormatter) for which each class had its custom
implementations of the headings and row methods.  I don't see much real
benefit to having the original TableFormatter class as used here.  Am I
wrong to think this?  At best it gives a single place to look to remind a
coder what methods are intended to be implemented for all subclasses, but
does not constrain the coder to do so.

OTOH, this inspired me to read up a bit on actual abstract base classes
(ABC), which *do* force the coder to implement the methods of the ABC or it
will not allow one to instantiate the method-deficient subclass.  I can see
some benefit to this approach.  Of course, Beazley may be planning on
heading in the true ABC direction later in the material.

What are your thoughts?  Perhaps a fuller explanation for noobie boB?

-- 
Wishing you only the best,

boB Stepp

From __peter__ at web.de  Mon Jun  8 08:51:27 2020
From: __peter__ at web.de (Peter Otten)
Date: Mon, 08 Jun 2020 14:51:27 +0200
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
References: <20200608030250.GF10604@Dream-Machine1>
Message-ID: <rblc8g$1gbo$1@ciao.gmane.io>

boB Stepp wrote:

> Now in "4.2 Inheritance" at
> https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html
> 
> class TableFormatter:
>      def headings(self, headers):
>          '''
>          Emit the table headings.
>          '''
>          raise NotImplementedError()
> 
>      def row(self, rowdata):
>          '''
>          Emit a single row of table data.
>          '''
>          raise NotImplementedError()
> 
> with the comment:
> 
> "This class does nothing

> What are your thoughts?

Dunno. Maybe writing code that does nothing is an art form, like poems or 
songs... and mypy is your arbiter elegantiarum. 



From alan.gauld at yahoo.co.uk  Mon Jun  8 11:29:32 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 8 Jun 2020 16:29:32 +0100
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <20200608030250.GF10604@Dream-Machine1>
References: <20200608030250.GF10604@Dream-Machine1>
Message-ID: <rbllgs$2vau$1@ciao.gmane.io>

I posted this earlier today but it seems to have vanished into
bit dust... trying again...


On 08/06/2020 04:02, boB Stepp wrote:

> implementations of the headings and row methods.  I don't see
> much real benefit to having the original TableFormatter class
> as used here.  Am I wrong to think this?

You may be right in this specific case and, as you say, Beazley
is probably going to add features that make it more useful.

But in the general case abstract classes are the fundamental building
blocks of most OOP systems. You generalize the entities within the
system into a smallish set of interacting abstract classes. You build
the system using those abstract classes. In that way the entire core
logic of your system is expressed in abstract terms. Then you start
building the concrete versions of those abstractions and slotting them
into the system. You don't need to modify the abstract code because the
objects are polymorphic and will respond exactly like the abstract
versions (except they actually do something!).

So abstract classes are of limited value in isolation, it's when you get
a group of them acting according to some pattern of behaviour that they
become useful. Think about a GUI. It has Window objects(abstract) and
events (abstract) and possibly a Canvas(possibly abstract). You can then
design how window objects interact with each other and with events and
represent themselves on a canvas in purely abstract terms. Then start
building concrete widgets as subclasses of window. Create real
events(mouse, keyboard, network etc) and real canvases(screen, printer,
virtual) etc. The GUI framework will use these new classes with no new
work. And that's how almost all real-world GUI frameworks are built.

(The mixin style of multiple inheriance OOP is also based on the
idea of abstract mixins that you then replace with concrete
variations on the theme. But with mixins its normally a case
of partially implemented classes rather than pure abstracts
 - what C++ calls virtual classes.

-- 
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  Mon Jun  8 12:59:54 2020
From: jf_byrnes at comcast.net (Jim)
Date: Mon, 8 Jun 2020 11:59:54 -0500
Subject: [Tutor] pandas.to_clipboard() copies nothing
In-Reply-To: <rbiu5c$pbg$1@ciao.gmane.io>
References: <rbepsr$hj2$1@ciao.gmane.io> <rbfne0$1993$1@ciao.gmane.io>
 <rbgcpn$2qid$1@ciao.gmane.io> <rbgnu0$29ac$1@ciao.gmane.io>
 <rbhnq5$3hv4$1@ciao.gmane.io> <rbiaon$3e78$1@ciao.gmane.io>
 <rbiu5c$pbg$1@ciao.gmane.io>
Message-ID: <rblqqc$3cv6$1@ciao.gmane.io>

On 6/7/20 9:38 AM, Jim wrote:
> On 6/7/20 4:07 AM, Peter Otten wrote:
>> Jim wrote:
>>
>>> You certainly know more about this than I do, but I wonder about the
>>> conclusion that xclip is not found.
>>
>> I don't know much, "qt tried as last resort" is my interpretation of the
>> latest pandas code, without actually running it.
> 
> 
> 
>>> I don't think I need QT any more so I am going to stop trying to figure
>>> this out and try to finish the script I was working on. I do plan on
>>> coming back and see if there is a different solution other than deleting
>>> PyQt5.
>>
>> Did you try invoking
>>
>> pandas.io.clipboard.set_clipboard("xclip")
>>
>> before pasting?
> 
> No unfortunately I did not. I wanted to get back to working on the 
> script that exposed this mess so when deleting the QT stuff worked I 
> just moved on. Once I get that script running I plan on re-installing QT 
> and see what happens.
> 

Ok, so I reloaded PyQt5, here's what happened:

(env36) jfb at jims-mint18 ~ $ pip install PyQt5
Collecting PyQt5
   Using cached 
PyQt5-5.15.0-5.15.0-cp35.cp36.cp37.cp38-abi3-manylinux2014_x86_64.whl 
(76.6 MB)
Collecting PyQt5-sip<13,>=12.8
   Using cached PyQt5_sip-12.8.0-cp36-cp36m-manylinux1_x86_64.whl (277 kB)
Installing collected packages: PyQt5-sip, PyQt5
Successfully installed PyQt5-5.15.0 PyQt5-sip-12.8.0

The results of running the test file:

(env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even 
though it was found.
This application failed to start because no Qt platform plugin could be 
initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, 
offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, 
wayland-xcomposite-glx, webgl, xcb.

Aborted

Here I tried adding set_clipboard:

(env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py
Traceback (most recent call last):
   File "/home/jfb/Dev/Python/test_csv_file.py", line 11, in <module>
     pandas.io.clipboard.set_clipboard("xclip")
AttributeError: module 'pandas.io' has no attribute 'clipboard'
(env36) jfb at jims-mint18 ~ $


I googled the error and found references to it going back to 2013. Most 
solutions were aimed at people developing with PyQt, add debug 
statements etc. Some seemed  to aimed at users and suggested tinkering 
with simlinks, paths and installing additional packages. Most of them I 
did not fully understand.

Anyway I have my solution. Delete PyQt5 and the problem goes away. If I 
ever want to use QT again, setup a new VE and never run pandas in it.

Regards,  Jim


From robertvstepp at gmail.com  Mon Jun  8 14:00:53 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 8 Jun 2020 13:00:53 -0500
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <rbllgs$2vau$1@ciao.gmane.io>
References: <20200608030250.GF10604@Dream-Machine1>
 <rbllgs$2vau$1@ciao.gmane.io>
Message-ID: <CANDiX9J2F2xjN33W0np-ixm5=NUxNkR8z5WeASX8zj+Q-RzGXQ@mail.gmail.com>

On Mon, Jun 8, 2020 at 10:29 AM Alan Gauld via Tutor <tutor at python.org> wrote:
>
> I posted this earlier today but it seems to have vanished into
> bit dust... trying again...

I did receive the original email prior to it appearing on the Tutor Archive.

> But in the general case abstract classes are the fundamental building
> blocks of most OOP systems. You generalize the entities within the
> system into a smallish set of interacting abstract classes. You build
> the system using those abstract classes. In that way the entire core
> logic of your system is expressed in abstract terms. Then you start
> building the concrete versions of those abstractions and slotting them
> into the system. You don't need to modify the abstract code because the
> objects are polymorphic and will respond exactly like the abstract
> versions (except they actually do something!).
>
> So abstract classes are of limited value in isolation, it's when you get
> a group of them acting according to some pattern of behaviour that they
> become useful. Think about a GUI. It has Window objects(abstract) and
> events (abstract) and possibly a Canvas(possibly abstract). You can then
> design how window objects interact with each other and with events and
> represent themselves on a canvas in purely abstract terms. Then start
> building concrete widgets as subclasses of window. Create real
> events(mouse, keyboard, network etc) and real canvases(screen, printer,
> virtual) etc. The GUI framework will use these new classes with no new
> work. And that's how almost all real-world GUI frameworks are built.

Hmm.  Then ABCs seem quite useful.  I wonder why I normally only see
mention of them as being advanced features?  If I am following you
they would seem very useful for anything beyond small, simple OO
programs.  Sounds like something that I probably should investigate if
I ever get a handle on the basic class writing stuff.

> (The mixin style of multiple inheriance OOP is also based on the
> idea of abstract mixins that you then replace with concrete
> variations on the theme. But with mixins its normally a case
> of partially implemented classes rather than pure abstracts
>  - what C++ calls virtual classes.

So these concepts are language-agnostic and broadly used?

Thanks!

-- 
boB

From robertvstepp at gmail.com  Mon Jun  8 14:10:21 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 8 Jun 2020 13:10:21 -0500
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <rblc8g$1gbo$1@ciao.gmane.io>
References: <20200608030250.GF10604@Dream-Machine1>
 <rblc8g$1gbo$1@ciao.gmane.io>
Message-ID: <CANDiX9+3Jiz+2-TeAttZga70Zk2NbrfDysQxgtZ3iaioqSkR0A@mail.gmail.com>

On Mon, Jun 8, 2020 at 7:52 AM Peter Otten <__peter__ at web.de> wrote:
>
> boB Stepp wrote:
>
> > Now in "4.2 Inheritance" at
> > https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html
> >
> > class TableFormatter:
> >      def headings(self, headers):
> >          '''
> >          Emit the table headings.
> >          '''
> >          raise NotImplementedError()
> >
> >      def row(self, rowdata):
> >          '''
> >          Emit a single row of table data.
> >          '''
> >          raise NotImplementedError()
> >
> > with the comment:
> >
> > "This class does nothing
>
> > What are your thoughts?
>
> Dunno. Maybe writing code that does nothing is an art form, like poems or
> songs... and mypy is your arbiter elegantiarum.

Totally unexpected, quirky response!  Who shall reign supreme in
directing my cyber-court: Black, MyPy or Pylint?  Pylint critiques
seemingly every choice, but will back down if challenged.  MyPy only
judges a subset of cyberlife.  And Black judges with an iron hand.
Perhaps off with him to the Coliseum fights to perish unless further
deemed worthy?
~(:>))

-- 
boB

From __peter__ at web.de  Mon Jun  8 16:59:50 2020
From: __peter__ at web.de (Peter Otten)
Date: Mon, 08 Jun 2020 22:59:50 +0200
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
References: <20200608030250.GF10604@Dream-Machine1>
 <rblc8g$1gbo$1@ciao.gmane.io>
 <CANDiX9+3Jiz+2-TeAttZga70Zk2NbrfDysQxgtZ3iaioqSkR0A@mail.gmail.com>
Message-ID: <rbm8sa$3pe1$1@ciao.gmane.io>

boB Stepp wrote:

> On Mon, Jun 8, 2020 at 7:52 AM Peter Otten <__peter__ at web.de> wrote:
>>
>> boB Stepp wrote:
>>
>> > Now in "4.2 Inheritance" at
>> > https://dabeaz-course.github.io/practical->> > python/Notes/04_Classes_objects/02_Inheritance.html
>> >
>> > class TableFormatter:
>> >      def headings(self, headers):
>> >          '''
>> >          Emit the table headings.
>> >          '''
>> >          raise NotImplementedError()
>> >
>> >      def row(self, rowdata):
>> >          '''
>> >          Emit a single row of table data.
>> >          '''
>> >          raise NotImplementedError()
>> >
>> > with the comment:
>> >
>> > "This class does nothing
>>
>> > What are your thoughts?
>>
>> Dunno. Maybe writing code that does nothing is an art form, like poems or
>> songs... and mypy is your arbiter elegantiarum.
> 
> Totally unexpected, quirky response!  Who shall reign supreme in
> directing my cyber-court: Black, MyPy or Pylint?  Pylint critiques
> seemingly every choice, but will back down if challenged.  MyPy only
> judges a subset of cyberlife.  And Black judges with an iron hand.
> Perhaps off with him to the Coliseum fights to perish unless further
> deemed worthy?
> ~(:>))
> 

I don't know Black; with pylint you can cheat a little and get a score of 10 
for your perfect code, or you can cheat some more and get a score of 10 for 
your heap of crap.

mypy on the other hand is open-ended.

Start with TableFormatter, do you want to feed it Any? Of course not, so

print_table(table: Table, formatter: TableFormatter)

We've already established that the table consists of header and rows

class Header:
    column_headers: Sequence[ColumnHeader]

class Rows:
    rows: Iterator[Row]

class Row:
    fields: Sequence[Field]

class Field:
    def format(format: FieldFormat) -> str

class StrField, FloatField, DatetimeField, YouNameItField,...

Table:
    rows: Rows
    header: Header

That looks safe except that we stated that fields are formatted as str. 
What if in addition to csv and text we want to write a binary format?

class Field:
    def format(format: FieldFormat) -> SerializedField

We are starting to get robust. We just need to come up with a FieldFormat 
that works for all subclasses. That can't be hard, so let's look elsewhere.

David used short strings to specify the Formatter -- not very robust, and
Python has enums since ... when? So

class TableFormatterType(enum.Enum):
    text = "txt"
    csv = "csv"

Not as good as the http guys with their Referer, but still nice.

Having another glimpse at our zoo of fields, how can we instantiate the 
right subclass? We certainly need a 

RowFieldFactory

and a

ColumnHeaderFactory.

While we're at it, a

TableFormatterFactory

to cope with our CSVTableFormatter, and TextTableFormatter is de rigueur.
Are we done? Oh dear, do you think our table springs into existence out of 
nowhere?

I'll leave the details of the TableBuilder, or, let's be precise, 
FormatableTableBuilder (or is it PrintableFormatableTableBuilder?) as an 
exercise for the reader...

That said, I feel a bit uneasy about the FieldFormat, we should do it right 
and use a FieldFormatter instead. That gives us flexibility; one formatter 
per field type, composable for width, alignment, color, font,
all governed by a nice little FieldFormatterFactory...



From cs at cskk.id.au  Mon Jun  8 04:58:48 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 8 Jun 2020 18:58:48 +1000
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <20200608030250.GF10604@Dream-Machine1>
References: <20200608030250.GF10604@Dream-Machine1>
Message-ID: <20200608085848.GA58604@cskk.homeip.net>

On 07Jun2020 22:02, boB Stepp <robertvstepp at gmail.com> wrote:
>Now in "4.2 Inheritance" at
>https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html
>
>class TableFormatter:
>    def headings(self, headers):
>        '''
>        Emit the table headings.
>        '''
>	raise NotImplementedError()
>....
>with the comment:
>
>"This class does nothing, but it serves as a kind of design specification
>for additional classes that will be defined shortly. A class like this is
>sometimes called an ?abstract base class.?"

I'd note that this code may well predate the ABC stdlib classes. Or 
Beaz' use of them. So this class to my eye has two benefits:

- like the stdlib ABC or any abstract base class in general, it lets you 
  outline the methods you intend to provide and describe their 
  semantics/behaviour - just specifying things like this helps makes 
  things clear in your mind _before_ you go to write the code

- like the recommended way to write ABC methods, these methods explode 
  in your face if you haven't overridden them. This is handy if you 
  forget things. And if you're doing test driven development, or just 
  having a decent test suite, this will aid in having those tests fail 
  if the implementation is incomplete

>OTOH, this inspired me to read up a bit on actual abstract base classes
>(ABC), which *do* force the coder to implement the methods of the ABC or it
>will not allow one to instantiate the method-deficient subclass.  I can see
>some benefit to this approach.  Of course, Beazley may be planning on
>heading in the true ABC direction later in the material.

That is the nice thing about the stdlib ABC stuff: an unoverridden 
@abstractmethod will actually cause the subclass definition to fail, 
effectively like a compile time failure. Instead of some explosion at 
runtime (ideally during testing).

However, just having an abstract base class like Baez' one is probably 
good design practice, particularly if you're going to make a few 
subclasses.

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

From cs at cskk.id.au  Sun Jun  7 22:15:32 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Mon, 8 Jun 2020 12:15:32 +1000
Subject: [Tutor] Python 3 only: Better to use implicit or explicit
 "object" in class statements?
In-Reply-To: <20200607175133.GC10604@Dream-Machine1>
References: <20200607175133.GC10604@Dream-Machine1>
Message-ID: <20200608021532.GA17546@cskk.homeip.net>

On 07Jun2020 12:51, boB Stepp <robertvstepp at gmail.com> wrote:
>prefer being explicit with the latter.  I note that pylint prefers 
>omitting
>"(object)", calling it "useless-object-inheritance".

My lint script runs pylint with these items disabled:

  pylint_disable=bad-whitespace,bad-indentation,bad-continuation,invalid-name,useless-object-inheritance

Now, I might start stripping these back some more since I autoformat 
code more vigorously these days. But these complaints caused more noise 
than their cleanup warranted. For me.

>I realize that if I am trying to write code compatible with both Python 2
>and 3 that I need to explicitly inherit from "object".
>
>So, for Python 3 only development is there any consensus?  Are there any
>real arguments for being "explicit" with inheriting from "object"?  I have
>to say that I have not yet found the allusion to Zen to be explicit not
>convincing.

If I'm writing shiny new modules (thus, generally for Python 3 only 
unless I have some special purpose in mind), I omit the (object).

When maintaining legacy modules which might still be in play for Python 
2 programmes, I still use (object). because I don't need to break such 
modules gratuitously.

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

From hromero1231 at gmail.com  Mon Jun  8 23:21:29 2020
From: hromero1231 at gmail.com (harold Romero)
Date: Mon, 8 Jun 2020 23:21:29 -0400
Subject: [Tutor] I need help solving this
Message-ID: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com>

My program needs to have two input statements.  One will ask for the shape and the other for the location. 

The shape is limited to either a circle or a square.  If the user selects a circle the program needs to ask the user for the pen color.  The choices are red, blue or yellow.  All of the pen colors will determine a specific fill color.  Explore online to find a new fill color.  For instance if the user selects red as the pen color, the fill color will be pink (or whatever other color you want).  If the user selects a square the program needs to ask the user for a fill color.  The choices are red, blue or yellow.  These colors will determine the pen color.  For instance if the user selects blue for the fill color, the pen color can be green (or whatever other color you choose.

The location is limited to Top Left, Top Right, Bottom Left and Bottom Right.  If the user enters Top Left, then the pen size must be 3.  If the user enters Top Right, then pen size must be 5.  If the user enters Bottom Left, then the pen size must be 7.  Finally if the user enters Bottom Right then the pen size must be 9.


Im having a problem with have all four being drawn I just want one

From alan.gauld at yahoo.co.uk  Tue Jun  9 04:13:11 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 9 Jun 2020 09:13:11 +0100
Subject: [Tutor] I need help solving this
In-Reply-To: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com>
References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com>
Message-ID: <rbngan$1t2j$1@ciao.gmane.io>

On 09/06/2020 04:21, harold Romero wrote:
> My program needs to have two input statements.  One will ask for the shape and the other for the location. 

> Im having a problem with have all four being drawn I just want one

Without seeing your code we cannot begin to guess what you have done
wrong. But the intention of the exercise is obviously for you to capture
the input data and other choices as variables then draw one shape using
those variables as parameters. So there really shouldn't be 4 of them!


-- 
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  Tue Jun  9 13:42:18 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 9 Jun 2020 12:42:18 -0500
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <20200608085848.GA58604@cskk.homeip.net>
References: <20200608030250.GF10604@Dream-Machine1>
 <20200608085848.GA58604@cskk.homeip.net>
Message-ID: <CANDiX9KFvBfDOV6Weq_W71fonH4d7L0XeZwJTe3X1b3X04HLNg@mail.gmail.com>

On Mon, Jun 8, 2020 at 11:35 PM Cameron Simpson <cs at cskk.id.au> wrote:
>
> On 07Jun2020 22:02, boB Stepp <robertvstepp at gmail.com> wrote:
> >Now in "4.2 Inheritance" at
> >https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html
> >
> >class TableFormatter:
> >    def headings(self, headers):
> >        '''
> >        Emit the table headings.
> >        '''
> >       raise NotImplementedError()
> >....
> >with the comment:
> >
> >"This class does nothing, but it serves as a kind of design specification
> >for additional classes that will be defined shortly. A class like this is
> >sometimes called an ?abstract base class.?"
>
> I'd note that this code may well predate the ABC stdlib classes. Or
> Beaz' use of them. So this class to my eye has two benefits:

I did not consider this.  Plus now that I am being better exposed to
the design benefits of doing ABCs -- the above or the now standard
library version -- I can now see why he wanted to make this point.

> - like the stdlib ABC or any abstract base class in general, it lets you
>   outline the methods you intend to provide and describe their
>   semantics/behaviour - just specifying things like this helps makes
>   things clear in your mind _before_ you go to write the code

Another point that did not occur to me.

> - like the recommended way to write ABC methods, these methods explode
>   in your face if you haven't overridden them. This is handy if you
>   forget things. And if you're doing test driven development, or just
>   having a decent test suite, this will aid in having those tests fail
>   if the implementation is incomplete
>
> >OTOH, this inspired me to read up a bit on actual abstract base classes
> >(ABC), which *do* force the coder to implement the methods of the ABC or it
> >will not allow one to instantiate the method-deficient subclass.  I can see
> >some benefit to this approach.  Of course, Beazley may be planning on
> >heading in the true ABC direction later in the material.
>
> That is the nice thing about the stdlib ABC stuff: an unoverridden
> @abstractmethod will actually cause the subclass definition to fail,
> effectively like a compile time failure. Instead of some explosion at
> runtime (ideally during testing).

I had played with Beazley's example and noticed it would allow me to
instantiate a subclass, but would blow up if I did not override the
methods and tried to use them.

> However, just having an abstract base class like Baez' one is probably
> good design practice, particularly if you're going to make a few
> subclasses.

Your and Alan's comments have given me the sort of feedback I was
hoping for.  This OOP paradigm that I have mostly been avoiding I find
hard going in how to design and setup an approach.  Already written
classes I can usually parse out, but the why's of how the classes are
chosen and written I struggle with.  Especially when what is being
modeled is somewhat abstract, not a physical system like the trite
Animal -> Mammal -> Dog/Cat, etc. type examples that are prevalent.
For instance Beazley's chosen example is an excellent one for me to
struggle with as it falls (in my mind) into the more abstract type
system.  How to divy that up into meaningful classes I find difficult.

-- 
boB

From adameyring at gmail.com  Tue Jun  9 22:46:21 2020
From: adameyring at gmail.com (Adam Eyring)
Date: Tue, 9 Jun 2020 22:46:21 -0400
Subject: [Tutor] I need help solving this
In-Reply-To: <rbngan$1t2j$1@ciao.gmane.io>
References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com>
 <rbngan$1t2j$1@ciao.gmane.io>
Message-ID: <CAPStRW8-sDfJOQT24cP67eb6zznO-qW6PYy-b_wbGLdWd4SaTQ@mail.gmail.com>

If you set up your if statements correctly to respond to the user input,
you should only get one output. e.g.
i = input("(B)lue, (G)reen, (Y)ellow?")
if i == "B":
    draw blue circle
elif i == "G":
    draw green circle
else:
    draw yellow circle

AME

On Tue, Jun 9, 2020 at 4:13 AM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 09/06/2020 04:21, harold Romero wrote:
> > My program needs to have two input statements.  One will ask for the
> shape and the other for the location.
>
> > Im having a problem with have all four being drawn I just want one
>
> Without seeing your code we cannot begin to guess what you have done
> wrong. But the intention of the exercise is obviously for you to capture
> the input data and other choices as variables then draw one shape using
> those variables as parameters. So there really shouldn't be 4 of them!
>
>
> --
> 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 masonchristine12 at gmail.com  Tue Jun  9 22:29:11 2020
From: masonchristine12 at gmail.com (Christine Mason)
Date: Wed, 10 Jun 2020 14:29:11 +1200
Subject: [Tutor] Can anyone help answer this?
Message-ID: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>

Given the following class definition:

 class Food:

     def __init__(self, name, taste):

        self.name
<https://aus01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fself.name%2F&data=02%7C01%7Cchristine.massof%40ird.govt.nz%7C12c2d3472aba4bbc306f08d80ce1e902%7Cfb39e3e923a9404e93a2b42a87d94f35%7C1%7C0%7C637273511711638197&sdata=cM05RAGTtzn%2B1%2BDwU3c6UXadLKFLgyAR5iL2xJGte4g%3D&reserved=0>
= name

        self.taste = taste

 Write a function *createFood()* that takes a list of food items as
argument and creates an instance of class Food for each of them.  It then
returns the list of instances that it has created.

 Each food item in the list that is passed as argument to *createFood() *is
a tuple of the form ('name', 'taste'), so the list of food items might look
like this:

 [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')]

 The function *createFood() *takes the two elements of each tuple and
passes them to the initialiser of Food.  It then collects the objects
returned by the initialiser and adds them to the list that is returned by
createFood().

DO NOT call the function

From PyTutor at danceswithmice.info  Wed Jun 10 04:09:20 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Wed, 10 Jun 2020 20:09:20 +1200
Subject: [Tutor] Can anyone help answer this?
In-Reply-To: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
References: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
Message-ID: <3cc004f6-e00d-b87e-df02-ecb9b3127a34@DancesWithMice.info>

On 10/06/20 2:29 PM, Christine Mason wrote:
> Given the following class definition:
> 
>   class Food:
> 
>       def __init__(self, name, taste):
> 
>          self.name
> <https://aus01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fself.name%2F&data=02%7C01%7Cchristine.massof%40ird.govt.nz%7C12c2d3472aba4bbc306f08d80ce1e902%7Cfb39e3e923a9404e93a2b42a87d94f35%7C1%7C0%7C637273511711638197&sdata=cM05RAGTtzn%2B1%2BDwU3c6UXadLKFLgyAR5iL2xJGte4g%3D&reserved=0>
> = name
> 
>          self.taste = taste
> 
>   Write a function *createFood()* that takes a list of food items as
> argument and creates an instance of class Food for each of them.  It then
> returns the list of instances that it has created.
> 
>   Each food item in the list that is passed as argument to *createFood() *is
> a tuple of the form ('name', 'taste'), so the list of food items might look
> like this:
> 
>   [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')]
> 
>   The function *createFood() *takes the two elements of each tuple and
> passes them to the initialiser of Food.  It then collects the objects
> returned by the initialiser and adds them to the list that is returned by
> createFood().
> 
> DO NOT call the function


Is this an homework assignment? If so, for which course - and if you can 
give us on-line references, that's a bonus!

Assuming the above, we will be happy to *help* *you* find a solution. 
What code do you have so far? What results? Please copy-paste them into 
your reply.

For example:
- how do you instantiate an example of the Food class?
- how will you loop through each of the foods in the input list?tuple?
- how will you create, and then add, results to the output list?

The last injunction is badly-expressed. I presume that you are to 
forward your work to be graded as a function - and only a function (a 
common methodology to ease the grading process). However, to test your 
code, as a function, you will need to call it from somewhere! Either add 
a temporary function-call for testing (and remember to remove it before 
handing-in), or have you already learned about TDD (Test-Driven 
Development), eg pytest, unittest, ...?
-- 
Regards =dn

From alan.gauld at yahoo.co.uk  Wed Jun 10 05:44:55 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 10 Jun 2020 10:44:55 +0100
Subject: [Tutor] I need help solving this
In-Reply-To: <CAPStRW8-sDfJOQT24cP67eb6zznO-qW6PYy-b_wbGLdWd4SaTQ@mail.gmail.com>
References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com>
 <rbngan$1t2j$1@ciao.gmane.io>
 <CAPStRW8-sDfJOQT24cP67eb6zznO-qW6PYy-b_wbGLdWd4SaTQ@mail.gmail.com>
Message-ID: <rbqa2o$qd4$1@ciao.gmane.io>

On 10/06/2020 03:46, Adam Eyring wrote:
> If you set up your if statements correctly to respond to the user input,
> you should only get one output. e.g.
> i = input("(B)lue, (G)reen, (Y)ellow?")
> if i == "B":
>     draw blue circle
> elif i == "G":
>     draw green circle
> else:
>     draw yellow circle
> 
Or even better just set the parameters in the if statement
then draw the circle once at the end. That way you can
guarantee you only ever draw one circle even if you
somehow set more than one group of values..

col = input("(B)lue, (G)reen, (Y)ellow?")
if col == "B":
     set blue values
elif col == "G":
     set green values
else:
     set yellow values

draw_circle(values)

-- 
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 Jun 10 05:51:33 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 10 Jun 2020 10:51:33 +0100
Subject: [Tutor] Can anyone help answer this?
In-Reply-To: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
References: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
Message-ID: <rbqaf5$1oc4$1@ciao.gmane.io>

On 10/06/2020 03:29, Christine Mason wrote:
> Given the following class definition:
> 
>  class Food:
> 
>      def __init__(self, name, taste):
>         self.name = name
>         self.taste = taste
> 
>  Write a function *createFood()* that takes a list of food items as
> argument and creates an instance of class Food for each of them.  It then
> returns the list of instances that it has created.
> 
>  Each food item in the list that is passed as argument to *createFood() *is
> a tuple of the form ('name', 'taste'), so the list of food items might look
> like this:
> 
>  [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')]
> 
>  The function *createFood() *takes the two elements of each tuple and
> passes them to the initialiser of Food.  It then collects the objects
> returned by the initialiser and adds them to the list that is returned by
> createFood().

I really hate when students (and I assume is is a homework/tutorial
exercise) get asked to write bad code. This function should be
entirely unnecessary. The function for creating instances is the
constructor - it's already written. We don't need another.

And the Pythonic way of building lists is a list comprehension.
So this whole exercise should be reduced to:

food_list = [Food(t) for t in tuple_list]

If we are going to teach objects lets use the objects!

-- 
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 manpritsinghece at gmail.com  Wed Jun 10 04:32:28 2020
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 10 Jun 2020 14:02:28 +0530
Subject: [Tutor] Appropriate use of list comprehension
Message-ID: <CAO1OCwYKoXE0hVkLv48qN8qSmoht5EvAcYnBhHU1BKG2O9Tn_Q@mail.gmail.com>

Hi all ,

I just need to know that the way I have used to enter 3 names inside the
list , entered through keyboard, using list comprehension is syntactically
correct or not . Is there any other more efficient way to do this?
Below is the code given :

val = [input("enter name") for _ in range(3)]

val will be the list consisting those 3 names entered through keyboard.

Regards
Manprit Singh

From alan.gauld at yahoo.co.uk  Wed Jun 10 08:26:50 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 10 Jun 2020 13:26:50 +0100
Subject: [Tutor] Appropriate use of list comprehension
In-Reply-To: <CAO1OCwYKoXE0hVkLv48qN8qSmoht5EvAcYnBhHU1BKG2O9Tn_Q@mail.gmail.com>
References: <CAO1OCwYKoXE0hVkLv48qN8qSmoht5EvAcYnBhHU1BKG2O9Tn_Q@mail.gmail.com>
Message-ID: <rbqjia$2nfe$1@ciao.gmane.io>

On 10/06/2020 09:32, Manprit Singh wrote:
> I just need to know that the way I have used to enter 3 names inside the
> list , entered through keyboard, using list comprehension is syntactically
> correct or not .

The best check for syntax is the Python interpreter. if its happy then
the syntax is fine. You can try pylint and similar tools for more
critical analysis.

>  Is there any other more efficient way to do this?
> Below is the code given :
> 
> val = [input("enter name") for _ in range(3)]

Not more efficient no, but for production code you should wrap it
in a try/except block and usually, when reading user input in real
code, we need at least minimal data sanity checks. But you can
wrap that in a function and use the function in the comprehension.
It is a valid use of a comprehension if that's what you are asking.


-- 
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  Wed Jun 10 10:31:38 2020
From: __peter__ at web.de (Peter Otten)
Date: Wed, 10 Jun 2020 16:31:38 +0200
Subject: [Tutor] Can anyone help answer this?
References: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
 <rbqaf5$1oc4$1@ciao.gmane.io>
Message-ID: <rbqqsb$3mi2$1@ciao.gmane.io>

Alan Gauld via Tutor wrote:

> On 10/06/2020 03:29, Christine Mason wrote:
>> Given the following class definition:
>> 
>>  class Food:
>> 
>>      def __init__(self, name, taste):
>>         self.name = name
>>         self.taste = taste
>> 
>>  Write a function *createFood()* that takes a list of food items as
>> argument and creates an instance of class Food for each of them.  It then
>> returns the list of instances that it has created.
>> 
>>  Each food item in the list that is passed as argument to *createFood()
>>  *is
>> a tuple of the form ('name', 'taste'), so the list of food items might
>> look like this:
>> 
>>  [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')]
>> 
>>  The function *createFood() *takes the two elements of each tuple and
>> passes them to the initialiser of Food.  It then collects the objects
>> returned by the initialiser and adds them to the list that is returned by
>> createFood().
> 
> I really hate when students (and I assume is is a homework/tutorial
> exercise) get asked to write bad code. This function should be
> entirely unnecessary. 

It were unnecessary if it should create a single instance. For a whole list 
I think it's fine -- except that the name is misleading.

> The function for creating instances is the
> constructor - it's already written. We don't need another.
> 
> And the Pythonic way of building lists is a list comprehension.
> So this whole exercise should be reduced to:
> 
> food_list = [Food(t) for t in tuple_list]

You forgot the * which I think is an advanced and even somewhat questionable 
feature. 

To go to the other end of the spectrum of possible solutions, the teacher 
may well see attempts like

def create_food_list(pairs):
    for i in range(len(pairs)):
        name = pairs[i][0]
        taste = pairs[i][1]
        food = Food(name, taste)
        pairs[i] = food
    return pairs

which gives opportunities to show

- idiomatic iteration
- tuple unpacking
- good ways for a function to communicate with its caller.

You may argue that this should have been taught before starting with custom 
objects...
 
> If we are going to teach objects lets use the objects!




From PyTutor at danceswithmice.info  Wed Jun 10 16:41:13 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Thu, 11 Jun 2020 08:41:13 +1200
Subject: [Tutor] Can anyone help answer this?
In-Reply-To: <rbqaf5$1oc4$1@ciao.gmane.io>
References: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
 <rbqaf5$1oc4$1@ciao.gmane.io>
Message-ID: <1868d1f4-4098-a84a-9eb4-a8a6e5f77a03@DancesWithMice.info>

On 10/06/20 9:51 PM, Alan Gauld via Tutor wrote:

> I really hate when students (and I assume is is a homework/tutorial
> exercise) get asked to write bad code. This function should be
> entirely unnecessary. The function for creating instances is the
> constructor - it's already written. We don't need another.
...

> If we are going to teach objects lets use the objects!


That's one of two reasons for requesting that such students (one 
imagines) provide the course/source information. Students routinely 
grumble about 'the difficulty of assignments' and not understanding 
their wording. That's one thing. However, when practicing professionals 
and other tutors have criticisms, could?should we do something about the 
very problem that @Alan exposes.


That said, it can be difficult to comprehend, from a (?lost) student's 
struggles with a single assignment, the sequence of presentation the 
tutor is using. Let's take, for example, @boB's recent question on abc-s 
(that didn't actually use an abc). There are many ways to answer his 
question, but too many such 'answers' actually have the potential to 
confuse or even de-rail DaBeaz's chosen step-by-step approach. As 
mentioned to @boB (possibly privately) I have too much respect for that 
tutor to want to leap in and (arrogantly, appear to) 'correct' the 
methods he employs. Whereas, at the end of the course, if the trainee is 
still 'lost' and unable to exhibit a well-rounded understanding of 
Python, development, objects, OOP; that would be a different story!

Which leads me to the other end of the spectrum: there are lazy tutors 
who simply copy questions and chuck them 'over the wall' at a class, 
without any pedagogical consideration or care (I've seen them AND fired 
'em!). NB I'm not saying that applies in the case of the OP or of that 
Tutor! However, given the expertise available on-the-list, perhaps it 
would not be out-of-place to also adopt a r?le of helping tutors to 
improve their assignments, and thus, the quality of their training and 
commensurately, of the abilities of their graduates to use Python?
-- 
Regards =dn

From robertvstepp at gmail.com  Wed Jun 10 20:37:35 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 10 Jun 2020 19:37:35 -0500
Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type
 annotation errors)
In-Reply-To: <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info>
References: <20200606014015.GQ23247@Dream-Machine1>
 <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info>
Message-ID: <CANDiX9+Z-h1MfqZk1XjbwRdEJeUS0=ryS+YSbCGq9yJ0nOQsMQ@mail.gmail.com>

On Sat, Jun 6, 2020 at 9:45 PM DL Neil via Tutor <tutor at python.org> wrote:

> Given that 'the other David' has been a trainer almost as long as I (but
> he as a Python trainer - which I am (formally) not!), it seemed
> reasonable teaching technique/planning that the course would build
> further (per more-recent messages to this list). Perhaps the assertion
> of it being a useful utility back-then, was somewhat premature, and
> better applied to its 'final' iteration of development?

I am more than two-thirds through.  I could not stand the suspense,
and skimmed through all of the remaining sections and exercises.  I
must report that at the end of the course the function under critique
still returns either a list of dicts or a list of tuples depending on
whether headers are present or not.  Make of this what you will.

-- 
boB

From Richard at Damon-Family.org  Wed Jun 10 22:03:33 2020
From: Richard at Damon-Family.org (Richard Damon)
Date: Wed, 10 Jun 2020 22:03:33 -0400
Subject: [Tutor] Pythonic Style Question
Message-ID: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>

Background:

Long time programmer (started with punch cards) but fairly new to punch
cards, but fairly new to Python.

Working on a program that will be a moderate size program when done, and
doing it in Python as it looks to be a reasonable choice, and a good
learning experience.

Decided to try running pylint on it to see what sort or 'Preferred
Style' it would lead me to (might as well have something look over the
code and critique it) (I know the weaknesses of Linters, but worth a shot)

Getting a lot of coding style errors for module global variables that
seem to be a reasonable way to do it, but figured I would ask to see if
there is a more Pythonic method to do these.

Example, application will have a number of settings stored in a
configuration file, so I have a myconfig.py module that is called with
the path to the config file, that uses configparser to read in the
options and create a module global variable (config) that other parts of
the system can import, and then query/set by accessing.

pylint first complains that these 'constants' should be in ALL_CAPS (but
they aren't constants, so I don't think they should be ALL_CAPS), and in
the function that will set it up, complains of the global statement so
it can access the module global. I could also create my own access
wrappers to get/set options, that other modules will call, but I would
think I would still need the module global (and making it _config to
mark it as a non-global still gets all the warnings about the constant
not being ALL_CAPS).

Is there another better way to do this sort of thing? or is pylint just
being over picky (as lints are prone to be) and I need to put a comment
on the statement to tell pylint it is ok?

-- 
Richard Damon


From PyTutor at danceswithmice.info  Wed Jun 10 22:11:01 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Thu, 11 Jun 2020 14:11:01 +1200
Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type
 annotation errors)
In-Reply-To: <CANDiX9+Z-h1MfqZk1XjbwRdEJeUS0=ryS+YSbCGq9yJ0nOQsMQ@mail.gmail.com>
References: <20200606014015.GQ23247@Dream-Machine1>
 <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info>
 <CANDiX9+Z-h1MfqZk1XjbwRdEJeUS0=ryS+YSbCGq9yJ0nOQsMQ@mail.gmail.com>
Message-ID: <d24ed33b-6efe-9de3-5df1-bccf3eeaded6@DancesWithMice.info>

On 11/06/20 12:37 PM, boB Stepp wrote:
> On Sat, Jun 6, 2020 at 9:45 PM DL Neil via Tutor <tutor at python.org> wrote:
> 
>> Given that 'the other David' has been a trainer almost as long as I (but
>> he as a Python trainer - which I am (formally) not!), it seemed
>> reasonable teaching technique/planning that the course would build
>> further (per more-recent messages to this list). Perhaps the assertion
>> of it being a useful utility back-then, was somewhat premature, and
>> better applied to its 'final' iteration of development?
> 
> I am more than two-thirds through.  I could not stand the suspense,
> and skimmed through all of the remaining sections and exercises.  I
> must report that at the end of the course the function under critique
> still returns either a list of dicts or a list of tuples depending on
> whether headers are present or not.  Make of this what you will.


Perhaps then you should first finish the course, and then figure-out his 
'what's next'. Possibly the story continues?
[by then you will have basic Python objectives achieved]

Failing that, revert and in a new msg/thread re-ask the question - 
perhaps stating the problem as a user request or series of "user 
stories"; and then asking how OOP-oriented pythonista would go-about 
designing a solution (classes, methods, algorithms, ...)?
[which I believe is what you want to learn, under the "OOP" heading]
-- 
Regards =dn

From martin at linux-ip.net  Wed Jun 10 23:07:29 2020
From: martin at linux-ip.net (Martin A. Brown)
Date: Wed, 10 Jun 2020 20:07:29 -0700
Subject: [Tutor] Pythonic Style Question
In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
Message-ID: <alpine.LSU.2.20.2006101922060.6672@qnttre.jbaqresebt.arg>


Hello there,

>Long time programmer (started with punch cards) but fairly new to 
>Python.

As a kid, I played with the detritus that held leftover programs 
.... on punch cards.

Both parents wrote in COBOL.  (Imagine what data security 
professionals of today would say about some kid playing with the 
residual fragments of intellectual property.)

>Decided to try running pylint on it to see what sort or 'Preferred 
>Style' it would lead me to (might as well have something look over 
>the code and critique it) (I know the weaknesses of Linters, but 
>worth a shot)
>
>Getting a lot of coding style errors for module global variables 
>that seem to be a reasonable way to do it, but figured I would ask 
>to see if there is a more Pythonic method to do these.

Quite possibly!  But, see below for more commentary on interpreting 
what you are seeing.

>Example, application will have a number of settings stored in a 
>configuration file, so I have a myconfig.py module that is called 
>with the path to the config file, that uses configparser to read in 
>the options and create a module global variable (config) that other 
>parts of the system can import, and then query/set by accessing.

If you show the code (or small sections), we may be able to help you 
find ways to avoid the warnings from globals.  This is, of course, a 
stylistic choice that pylint is complaining about.  Usually, it's 
possible to read the configuration data in myconfig.py and then use 
an import to put the name into the namespace of another problem 
(without making it global), and then pass it into any objects or 
functions which may need the configurables that came from that 
original configuration file.

Mostly, the solution to that problem is around how to use variable 
scope.  I'd imagine that any language you've come from probably had 
definitions of variable scope, so that's probably not a new idea.  
Here's the place in the Python docs to read about that:

  https://docs.python.org/3/reference/executionmodel.html#resolution-of-names

Of course, it's not forbidden to use globally scoped variables, it's 
generally discouraged since many future sins (or bugs) can be 
avoided by considering scope at first-writing.  I believe this would 
fall into the category of a "code smell" according to pylint, which 
is why it objects and complains.

>pylint first complains that these 'constants' should be in ALL_CAPS 
>(but they aren't constants, so I don't think they should be 
>ALL_CAPS), and in the function that will set it up, complains of 
>the global statement so it can access the module global. I could 
>also create my own access wrappers to get/set options, that other 
>modules will call, but I would think I would still need the module 
>global (and making it _config to mark it as a non-global still gets 
>all the warnings about the constant not being ALL_CAPS).

You are right about there being no 'constants' in Python (though 
there are some third-party libraries that try to fake that).

If you don't actually need to emulate constants or provide get/set 
style methods, I'd say don't bother (there's a human's opinion as 
opposed to pylint's expression of some other humans' opinions).  
I.e. if you won't be offering it as a module or library to others, 
then, why bother with the overhead of getters and setters?

>Is there another better way to do this sort of thing? or is pylint 
>just being over picky (as lints are prone to be) and I need to

Whether the perfect critic, picky or overly picky is entirely up to 
you.  I can tell you that when I run it on some of my sample code 
written to demonstrate the language I get fantastic scores.  When I 
run it against some (reasonably well-tested) production code (which 
lacks the message control exemption comments), I don't get 
particularly good scores.  Why?

  * Because some code has runtime characteristics that pylint cannot 
    predict, so views with skepticism.
  * Because for temporary variables, I actually like one-letter 
    characters. (o for object, d for dict, l for list, s for string)
  * Because (perhaps shame on me) not all of my functions have 
    docstrings.

And, some other such problems.  I'm OK with not getting a 
particularly high score from pylint because I know why I have made 
most of those decisions (or the law of diminishing returns for 
effort have kicked in).

The pylint manual introduction is reasonably self-aware about this, 
too, which is nice.  It's a good tool (and actually, running it just 
now on some production code, I see some things that I might go back 
and revisit):

  https://pylint.readthedocs.io/en/latest/intro.html

> .. put a comment on the statement to tell pylint it is ok?

Yes, you certainly can:

  https://pylint.readthedocs.io/en/latest/user_guide/message-control.html

You can try it out by running:

  pylint -d line-too-long,invalid-name ./path/to/your/proggie.py

I haven't tried "# pylint: disable=line-too-long,invalid-name"

because I kind of like seeing the grousing, in the cases that I run 
pylint.  On the other hand, I do have some minimal expectations.  
While I rarely use pylint, but I hew (generally) to pyflakes and 
pep8, so I run the following as a part of continuous integration / 
or VCS hooks:

  flake8 --ignore E501

And, I ignore that one because, as a verbose lout, I sometimes end 
up with lines longer than 80 characters.

-Martin

-- 
Martin A. Brown
http://linux-ip.net/

From alan.gauld at yahoo.co.uk  Thu Jun 11 05:00:33 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 11 Jun 2020 10:00:33 +0100
Subject: [Tutor] Can anyone help answer this?
In-Reply-To: <rbqqsb$3mi2$1@ciao.gmane.io>
References: <CAAUeNh2td5X43iUM_x0CDch-vMFjRqgESYXtde4dM4w2aT3rbA@mail.gmail.com>
 <rbqaf5$1oc4$1@ciao.gmane.io> <rbqqsb$3mi2$1@ciao.gmane.io>
Message-ID: <rbsrrh$2n4o$1@ciao.gmane.io>

On 10/06/2020 15:31, Peter Otten wrote:

>> And the Pythonic way of building lists is a list comprehension.
>> So this whole exercise should be reduced to:
>>
>> food_list = [Food(t) for t in tuple_list]
> 
> You forgot the * which I think is an advanced and even somewhat questionable 
> feature. 

You are right, but its not needed here. We could still use a
comprehension with:

food_list = [Food(name,taste) for name,taste in tuple_list]

utilising tuple unpacking.


> which gives opportunities to show
> 
> - idiomatic iteration
> - tuple unpacking
> - good ways for a function to communicate with its caller.
> 
> You may argue that this should have been taught before starting with custom 
> objects...

Yes, that was my point. The exercise appears to be all about
instantiating objects, but then misses the whole point of
having objects in the first place - that the functionality
resides inside the object. Encouraging students to create
functions that just use the constructor to return a list
is bad practice and also teaching a bad way of thinking.
It is exactly this kind of teaching that results in the
poor understanding of OOP that we see so often today.

-- 
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  Thu Jun 11 06:28:22 2020
From: __peter__ at web.de (Peter Otten)
Date: Thu, 11 Jun 2020 12:28:22 +0200
Subject: [Tutor] Pythonic Style Question
References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
Message-ID: <rbt10a$2l30$1@ciao.gmane.io>

Richard Damon wrote:

> Background:
> 
> Long time programmer (started with punch cards) but fairly new to punch
> cards, but fairly new to Python.
> 
> Working on a program that will be a moderate size program when done, and
> doing it in Python as it looks to be a reasonable choice, and a good
> learning experience.
> 
> Decided to try running pylint on it to see what sort or 'Preferred
> Style' it would lead me to (might as well have something look over the
> code and critique it) (I know the weaknesses of Linters, but worth a shot)
> 
> Getting a lot of coding style errors for module global variables that
> seem to be a reasonable way to do it, but figured I would ask to see if
> there is a more Pythonic method to do these.
> 
> Example, application will have a number of settings stored in a
> configuration file, so I have a myconfig.py module that is called with
> the path to the config file, that uses configparser to read in the
> options and create a module global variable (config) that other parts of
> the system can import, and then query/set by accessing.

Do you use the global statement to rebind the global `config` name

def read_config()
    global config
    config = ...
read_config()

or to modify it

def update_config():
    global config
    config.working_directory = ...

? In the second example `global` is unnecessary, in the first you might at 
least consider changing it to

def read_config():
    config = ...
    return config
config = read_config()

> pylint first complains that these 'constants' should be in ALL_CAPS (but
> they aren't constants, so I don't think they should be ALL_CAPS),

I think that's indeed very annoying. I sometimes ignore it and sometimes 
tinker with the config file's const-rgx.

If I understand

http://pylint.pycqa.org/en/latest/whatsnew/2.5.html

correctly the situation may have improved.

> and in
> the function that will set it up, complains of the global statement so
> it can access the module global. I could also create my own access
> wrappers to get/set options, that other modules will call, but I would
> think I would still need the module global (and making it _config to
> mark it as a non-global still gets all the warnings about the constant
> not being ALL_CAPS).
> 
> Is there another better way to do this sort of thing? or is pylint just
> being over picky (as lints are prone to be) and I need to put a comment
> on the statement to tell pylint it is ok?

Having as few global variables as possible (but not fewer) seems a good idea 
to me.



From alan.gauld at yahoo.co.uk  Thu Jun 11 06:45:40 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 11 Jun 2020 11:45:40 +0100
Subject: [Tutor] Pythonic Style Question
In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
Message-ID: <rbt20k$sbm$1@ciao.gmane.io>

On 11/06/2020 03:03, Richard Damon wrote:
> Long time programmer (started with punch cards)

You are not alone on this list, although in my case it was paper tape...

> Getting a lot of coding style errors for module global variables that
> seem to be a reasonable way to do it, but figured I would ask to see if
> there is a more Pythonic method to do these.

As an experienced programmer i'm sure you know why globals are generally
frowned on and the usual techniques for getting rid of them (pass as
function parameters return as values etc.)

> Example, application will have a number of settings stored in a
> configuration file, so I have a myconfig.py module that is called with
> the path to the config file, that uses configparser to read in the
> options and create a module global variable (config) that other parts of
> the system can import, and then query/set by accessing.

A lot depends on what kind of data you are storing but one common trick
for dealing with shared constants etc is to put them in a python module
and then import that module into every other module that requires
access. You can then edit the python module when you want to modify the
settings.

######## my_globals.py  #####
SIZE = 42
SCALE = 66
label = "My funky app"
#############################


##### Myapp.py  #####

import my_globals as globals


print (The size is: ", globals.SIZE)
globals.label = input("What label do you want? ")

etc...

Not sure if that helps at all but its something
that non-python programmers often overlook as
a possibility.

Obviously there are security/reliability issues in
allowing users to modify the code, but thats true
any time you ship source. If its on a server or other
secured location or its for your own use then it
should be OK.

-- 
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 Richard at Damon-Family.org  Thu Jun 11 07:19:55 2020
From: Richard at Damon-Family.org (Richard Damon)
Date: Thu, 11 Jun 2020 07:19:55 -0400
Subject: [Tutor] Pythonic Style Question
In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org>
Message-ID: <6f40e4e8-1edb-01f1-2478-66109bb5301c@Damon-Family.org>

On 6/10/20 10:03 PM, Richard Damon wrote:
> Background:
>
> Long time programmer (started with punch cards) but fairly new to punch
> cards, but fairly new to Python.
>
> Working on a program that will be a moderate size program when done, and
> doing it in Python as it looks to be a reasonable choice, and a good
> learning experience.
>
> Decided to try running pylint on it to see what sort or 'Preferred
> Style' it would lead me to (might as well have something look over the
> code and critique it) (I know the weaknesses of Linters, but worth a shot)
>
> Getting a lot of coding style errors for module global variables that
> seem to be a reasonable way to do it, but figured I would ask to see if
> there is a more Pythonic method to do these.
>
> Example, application will have a number of settings stored in a
> configuration file, so I have a myconfig.py module that is called with
> the path to the config file, that uses configparser to read in the
> options and create a module global variable (config) that other parts of
> the system can import, and then query/set by accessing.
>
> pylint first complains that these 'constants' should be in ALL_CAPS (but
> they aren't constants, so I don't think they should be ALL_CAPS), and in
> the function that will set it up, complains of the global statement so
> it can access the module global. I could also create my own access
> wrappers to get/set options, that other modules will call, but I would
> think I would still need the module global (and making it _config to
> mark it as a non-global still gets all the warnings about the constant
> not being ALL_CAPS).
>
> Is there another better way to do this sort of thing? or is pylint just
> being over picky (as lints are prone to be) and I need to put a comment
> on the statement to tell pylint it is ok?
>
For the question of sample code, showing what I am doing myconfig.py

import configparser
# Path to the currently used config file
config_path = None

# Contents of the currently used configuration
config = None

def load_configuration(path):
??? """ Load the Configuration file """
??? global config_path
??? config_path = path
??? global config
??? config = configparser.ConfigParser()
??? config.read(path)
??? # Add Sections we will use if not present
??? if 'General' not in config.sections():
??????? config['General'] = {}
??? if 'Default' not in config.sections():
??????? config['Defaults'] = {}
??? if 'Recent' not in config.sections():
??????? config['Recent'] = {}
?? # other defaults added here
?? save_configuration()

def save_configuration():
??? """ Save the current configuration"""
??? with open(config_path, 'w') as configfile:
??????? config.write(configfile)

Now, config_path probably should be _config_path as other modules
shouldn't be using it. But many modules will be doing something like

import myconfig

#

??? data_dir = myconfig.config['General']['DataDirectory']

To get the directory which the user has specified to put the various
data files for the program.

Yes, lots of globals are a sign of a problem, but this sort of config
data has bits for lots of parts of the program, and making each part
read its own data sounds worse, and just pushes down to problem as then
the name of the config file needs to be global, as it can be overridden
at program startup.

I suppose I could get rid of the global config statement by initializing
config to the configparser at the global level, but the None
initialization will create an error if I try to use the config
information before I call myconfig.load_configuration(). I am using a
recent version (2.5.2) but maybe the None initialization is what is
making it think it is a constant. Initializing it to the ConfigParser at
global scope does make it no longer get flagged as constant

Now, the final answer is probably adding the #pylint comments around the
sections containing the unrecognized module globals, and treat them as
the mark that I have made the deliberate decision to 'bend the rules'
(at least as interpreted by pylint).

-- 
Richard Damon


From john at johnweller.co.uk  Fri Jun 12 13:59:16 2020
From: john at johnweller.co.uk (John Weller)
Date: Fri, 12 Jun 2020 18:59:16 +0100
Subject: [Tutor] Reading a CSV file
Message-ID: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>

I have a CSV file with 366 rows each with 4 comma separated fields; day_no,
date, sunrise, sunset.  The top row contains the field names.  I want access
the time of sunrise and sunset from file for a particular day_no.

 

I have tried:

 

import csv

 

with open('sun_times_gmt.csv', newline= '') as csvfile:

    sun_times = csv.DictReader(csvfile, delimiter=',')

    for row in sun_times:

        print(row['sunrise'])

 

but it prints out the entire column.  How do I specify a particular row?

 

TIA

 

John Weller

01380 723235

07976 393631

 


From david at graniteweb.com  Fri Jun 12 18:42:57 2020
From: david at graniteweb.com (David Rock)
Date: Fri, 12 Jun 2020 17:42:57 -0500
Subject: [Tutor] Reading a CSV file
In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
Message-ID: <20200612224257.GX27796@apple.graniteweb.com>

* John Weller <john at johnweller.co.uk> [2020-06-12 18:59]:
> I have a CSV file with 366 rows each with 4 comma separated fields; day_no,
> date, sunrise, sunset.  The top row contains the field names.  I want access
> the time of sunrise and sunset from file for a particular day_no.
> 
>  
> 
> I have tried:
> 
>  
> 
> import csv
> 
> with open('sun_times_gmt.csv', newline= '') as csvfile:
>     sun_times = csv.DictReader(csvfile, delimiter=',')
>     for row in sun_times:
>         print(row['sunrise'])
> 
> 
> but it prints out the entire column.  How do I specify a particular row?

This is because you are telling it to print every row.  You need to add
an if statement that prints only if day_no matches the entry you want.
For example:

with open('sun_times_gmt.csv', newline= '') as csvfile:
    sun_times = csv.DictReader(csvfile, delimiter=',')
    for row in sun_times:
        if row['day_no'] == 'your day_no value here':
            print(row['sunrise'])


You could also play around with using the value of day_no to be a key
for the data so you can access it more directly.  If day_no is unique,
you can do this:

days = {}
with open('sun_times_gmt.csv', newline= '') as csvfile:
    sun_times = csv.DictReader(csvfile, delimiter=',')
    for row in sun_times:
        days[row['day_no']] = row

print(days['your day_no value here']['sunrise'])


It depends on exactly how you want to reference the data later

-- 
David Rock
david at graniteweb.com

From cs at cskk.id.au  Fri Jun 12 18:46:38 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 13 Jun 2020 08:46:38 +1000
Subject: [Tutor] Reading a CSV file
In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
Message-ID: <20200612224638.GA98411@cskk.homeip.net>

On 12Jun2020 18:59, John Weller <john at johnweller.co.uk> wrote:
>I have a CSV file with 366 rows each with 4 comma separated fields; day_no,
>date, sunrise, sunset.  The top row contains the field names.  I want access
>the time of sunrise and sunset from file for a particular day_no.
>
>I have tried:
>
>import csv
>
>with open('sun_times_gmt.csv', newline= '') as csvfile:
>    sun_times = csv.DictReader(csvfile, delimiter=',')
>    for row in sun_times:
>        print(row['sunrise'])
>
>but it prints out the entire column.  How do I specify a particular 
>row?

By putting the print inside an if-statement that recognises the row.  So 
changing:

    for row in sun_times:
        print(row['sunrise'])

into:

    for row in sun_times:
        if some test of row['day_no']:
            print(row['sunrise'])

which will cause the print statement to only work if the test succeeds.  
What the test is depends on what "a particular day_no" means.

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

From alexkleider at protonmail.com  Fri Jun 12 21:30:22 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Sat, 13 Jun 2020 01:30:22 +0000
Subject: [Tutor] Reading a CSV file
In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
Message-ID: <Gj0FaRzSwbNj1HvY5r_kaEduMOre9FjGku_fMFK4rMhbf7Z2wYmdofVTp7RB2UBwJb67rwZ2UZkgJzDF0yvS-aenn_P2bmHKVVQSxTvWusU=@protonmail.com>

??????? Original Message ???????
On Friday, June 12, 2020 10:59 AM, John Weller <john at johnweller.co.uk> wrote:

> I have a CSV file with 366 rows each with 4 comma separated fields; day_no,
> date, sunrise, sunset. The top row contains the field names. I want access
> the time of sunrise and sunset from file for a particular day_no.
> I have tried:
> import csv
> with open('sun_times_gmt.csv', newline= '') as csvfile:
> sun_times = csv.DictReader(csvfile, delimiter=',')
> for row in sun_times:
> print(row['sunrise'])
> but it prints out the entire column. How do I specify a particular row?
> TIA
> John Weller

Try adding an if statements as follows:

for row in sun_times:
    if row['day_no'] == my_day_number:
        print(row['sunrise'])



From david at graniteweb.com  Sat Jun 13 12:18:18 2020
From: david at graniteweb.com (David Rock)
Date: Sat, 13 Jun 2020 11:18:18 -0500
Subject: [Tutor] Reading a CSV file
In-Reply-To: <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk>
References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
 <20200612224257.GX27796@apple.graniteweb.com>
 <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk>
Message-ID: <20200613161818.GG27796@apple.graniteweb.com>

* John Weller <john at johnweller.co.uk> [2020-06-13 15:59]:
> Many thanks to all who replied.  I hoped it would be something like a
> dictionary.  The docs say that a dictionary is a sequence of key pairs -
> key:value but it appears that the value can be several fields.  Is this the
> case?

No. Dictionaries are key:value pairs, but "value" can be any type of object.
For example, the "value" could be another dictionary, a list, etc; all
of which have the potential to hold multiple items, not just a single
value.

> This program is intended to run 24/7 getting data every 10 minutes and using
> it to control equipment dependent on whether it is day or night.  There will
> be a setup function and a loop function.  I assume I can put the first part
> to create the dictionary is setup and the call in the loop?

Yes, that's exactly how my example is being used in stuff I'm doing.
Load the data into a dictionary once and reference it later.  It's a lot
faster than repeatedly walking the file.  The only reason to do that
would be if the data you are reading from changes every time.  If it's a
static table, read it once and reference the dictionary instead.

Another thing you my find handy is the pretty print module (pprint).  As
a test, after you create your sun_times OrderedDict with the csv module,
try doing:

pprint.pprint(sun_times)

to get a solid understanding of the layout of the dictionary created by
the csv module.

-- 
David Rock
david at graniteweb.com

From 1611kjb at gmail.com  Sat Jun 13 12:27:49 2020
From: 1611kjb at gmail.com (Michael Deslippe)
Date: Sat, 13 Jun 2020 16:27:49 +0000
Subject: [Tutor] Inclusivity
Message-ID: <YT1PR01MB30493489AD81A6CB80DE33E1A99E0@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>

When generating a random integer, ala;

myNum = random.randint(0, 1000000)

Is the range of integers inclusive or exclusive of the seed values (eg. will the range of possible answers include or exclude 0 and 1000000)?


---Mike

From john at johnweller.co.uk  Sat Jun 13 10:59:23 2020
From: john at johnweller.co.uk (John Weller)
Date: Sat, 13 Jun 2020 15:59:23 +0100
Subject: [Tutor] Reading a CSV file
In-Reply-To: <20200612224257.GX27796@apple.graniteweb.com>
References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk>
 <20200612224257.GX27796@apple.graniteweb.com>
Message-ID: <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk>

Many thanks to all who replied.  I hoped it would be something like a
dictionary.  The docs say that a dictionary is a sequence of key pairs -
key:value but it appears that the value can be several fields.  Is this the
case?

This program is intended to run 24/7 getting data every 10 minutes and using
it to control equipment dependent on whether it is day or night.  There will
be a setup function and a loop function.  I assume I can put the first part
to create the dictionary is setup and the call in the loop?

Thanks again

John

John Weller
01380 723235
07976 393631

-----Original Message-----
From: Tutor <tutor-bounces+john=johnweller.co.uk at python.org> On Behalf Of
David Rock
Sent: 12 June 2020 23:43
To: tutor at python.org
Subject: Re: [Tutor] Reading a CSV file

* John Weller <john at johnweller.co.uk> [2020-06-12 18:59]:
> I have a CSV file with 366 rows each with 4 comma separated fields; 
> day_no, date, sunrise, sunset.  The top row contains the field names.  
> I want access the time of sunrise and sunset from file for a particular
day_no.
> 
>  
> 
> I have tried:
> 
>  
> 
> import csv
> 
> with open('sun_times_gmt.csv', newline= '') as csvfile:
>     sun_times = csv.DictReader(csvfile, delimiter=',')
>     for row in sun_times:
>         print(row['sunrise'])
> 
> 
> but it prints out the entire column.  How do I specify a particular row?

This is because you are telling it to print every row.  You need to add an
if statement that prints only if day_no matches the entry you want.
For example:

with open('sun_times_gmt.csv', newline= '') as csvfile:
    sun_times = csv.DictReader(csvfile, delimiter=',')
    for row in sun_times:
        if row['day_no'] == 'your day_no value here':
            print(row['sunrise'])


You could also play around with using the value of day_no to be a key for
the data so you can access it more directly.  If day_no is unique, you can
do this:

days = {}
with open('sun_times_gmt.csv', newline= '') as csvfile:
    sun_times = csv.DictReader(csvfile, delimiter=',')
    for row in sun_times:
        days[row['day_no']] = row

print(days['your day_no value here']['sunrise'])


It depends on exactly how you want to reference the data later

--
David Rock
david at graniteweb.com
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


From swetha-m at lntnxt.com  Sat Jun 13 16:02:21 2020
From: swetha-m at lntnxt.com (Swetha M)
Date: Sat, 13 Jun 2020 20:02:21 +0000
Subject: [Tutor] Tensorflow Installation in Python Embedded Environment
Message-ID: <MAXPR01MB22228862200B98EBF97EFB78FD9E0@MAXPR01MB2222.INDPRD01.PROD.OUTLOOK.COM>

Hi,

I recently came across an issue while installing tensorflow library on Python Embedded environment(64-bit).
During installation, there was a library - 'termcolor' which showed up as error saying, module does not exist.
Then I tried installing only termcolor library thinking there can be version issue with tensorflow package. Same Error came up.
Since it used a cached version I thought there was a compatibility contradiction with the python environment in my system.
I tried all means to remove cached version, didn't work. And I had anaconda running, so I thought there was some environment path clash and stuff while trying to download from http.

I opened another command prompt, installed termcolor in the python environment of me system and it was installed successfully.

Then in the previous command prompt where installation of termcolor was failing, I tried the same command and it was installed without any errors.
Then I installed tensorflow and it was installed successfully too.

Although I was able to install, I would really like to know the root cause of this issue. I have attached some screenshots for reference. I would really appreciate any help on this particular issue.

Just for your notice, same scenario experienced in lower versions of python embedded too. (3.7)

Also, I have a few general queries:
Are there any differences at all between python installed in the system and using embedded package?
Can I use heavy libraries like tensorflow in the embedded environment?
Are there any performance related differences between those two methods?

Any help on these queries would be very helpful.

Thank You,

Regards,
Swetha M


Larsen & Toubro Limited

www.larsentoubro.com

This Email may contain confidential or privileged information for the intended recipient (s). If you are not the intended recipient, please do not use or disseminate the information, notify the sender and delete it from your system.

From alan.gauld at yahoo.co.uk  Sat Jun 13 18:44:27 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 13 Jun 2020 23:44:27 +0100
Subject: [Tutor] Inclusivity
In-Reply-To: <YT1PR01MB30493489AD81A6CB80DE33E1A99E0@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>
References: <YT1PR01MB30493489AD81A6CB80DE33E1A99E0@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>
Message-ID: <rc3ksb$3dro$1@ciao.gmane.io>

On 13/06/2020 17:27, Michael Deslippe wrote:
> When generating a random integer, ala;
> 
> myNum = random.randint(0, 1000000)
> 
> Is the range of integers inclusive or exclusive of the seed values 

When in doubt use the tools:

#############################
Help on method randint in module random:

randint(self, a, b) method of random.Random instance
    Return random integer in range [a, b], including both end points.
(END)
###########################



-- 
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 bouncingcats at gmail.com  Sat Jun 13 20:29:20 2020
From: bouncingcats at gmail.com (David)
Date: Sun, 14 Jun 2020 10:29:20 +1000
Subject: [Tutor] Inclusivity
In-Reply-To: <YT1PR01MB30493489AD81A6CB80DE33E1A99E0@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>
References: <YT1PR01MB30493489AD81A6CB80DE33E1A99E0@YT1PR01MB3049.CANPRD01.PROD.OUTLOOK.COM>
Message-ID: <CAMPXz=pE0UPxwghcTwqJthiAA6Tw2-xYfgObtxmSZVw4qaRLfQ@mail.gmail.com>

On Sun, 14 Jun 2020 at 08:43, Michael Deslippe <1611kjb at gmail.com> wrote:

> When generating a random integer, ala;
> myNum = random.randint(0, 1000000)
> Is the range of integers inclusive or exclusive of the seed values (eg. will the range of possible answers include or exclude 0 and 1000000)?

$ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> help(random.randint)
Help on method randint in module random:

randint(a, b) method of random.Random instance
    Return random integer in range [a, b], including both end points.

>>>

From krishp52 at rocketmail.com  Sun Jun 14 08:09:30 2020
From: krishp52 at rocketmail.com (Krish P)
Date: Sun, 14 Jun 2020 12:09:30 +0000 (UTC)
Subject: [Tutor] python
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
Message-ID: <1218488951.459090.1592136570249@mail.yahoo.com>

The Syracuse (also called the Collatz Hailstone) sequence is generated by starting with anatural number and repeatedly applying the following function:???(?) = ??/2, ?? ? ?? ????3? + 1, ?? ? ?? ???For example the Syracuse sequence starting with number 5 is: 5,16,8,4,2,1. This is an openquestion in mathematics whether this sequence will always go to 1 for every possible startingvalue.
Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications called ?data.txt?.This data file contains natural numbers, one on each line.1. Your role as a programmer is to create a program that will read all this data from the fileand generate the Syracuse sequence for each of those numbers.2. Additionally, you have to write every one of these Syracuse sequences into a file calledSyra.txt using your code.
data.txt:5171489041560302625118640372871807577663267444425332206991424075339339242048076287520376042156789972989546896669773172194641692345396892524370564098552375921179116691885394649252421723842536911736



From alan.gauld at yahoo.co.uk  Sun Jun 14 13:43:56 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 14 Jun 2020 18:43:56 +0100
Subject: [Tutor] python
In-Reply-To: <1218488951.459090.1592136570249@mail.yahoo.com>
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
 <1218488951.459090.1592136570249@mail.yahoo.com>
Message-ID: <rc5nkt$3mht$1@ciao.gmane.io>

On 14/06/2020 13:09, Krish P via Tutor wrote:
> ...your assignment specifications ...to create a program that will read all this data
> from the file and generate the Syracuse sequence for each 

> 2. Additionally, you have to write every one of these Syracuse sequence> into a file calledSyra.txt using your code.

It looks like you got a reasonable description of the problem to be
solved. How did you get on? Got any code yet? Does it work?
If so, well done!

If not, how would you like us to help?

What error messages do you get?
How close is the data out to what you expected?
What aspects of the assignment do you not understand?
Which OS are you using? Which python version?
Do you have programming experience in other languages?
Or are you a beginner?

The more you help us the more we can help you.

-- 
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 PyTutor at danceswithmice.info  Sun Jun 14 16:49:41 2020
From: PyTutor at danceswithmice.info (DL Neil)
Date: Mon, 15 Jun 2020 08:49:41 +1200
Subject: [Tutor] python
In-Reply-To: <1218488951.459090.1592136570249@mail.yahoo.com>
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
 <1218488951.459090.1592136570249@mail.yahoo.com>
Message-ID: <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info>

On 15/06/20 12:09 AM, Krish P via Tutor wrote:
> The Syracuse (also called the Collatz Hailstone) sequence...
> Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications...


In case you have not met "Moodle" before, it is an LMS (Learning 
Management System). It can be thought-of as a Content Management System 
with add-ons specifically designed for training, eg presenting lectures 
and papers, references, quizzes and exams, and so-forth. Think of it as 
the on-line equivalent of the binders of 'stuff' we used to accumulate 
as the academic year progressed (or the teacher's equivalent thereof).


Something else, of which you may be unaware: Another characteristic of 
today's education is that as well as the on-line teaching materials, 
there are also 'services', often known as "paper mills" or "term paper 
writing services", which offer to complete academic works - in exchange 
for money. Surprise, shock, horror! Thus, plagiarism and other enablers 
of 'cognitive by-pass learning' have exploded into a massive problem and 
dilute the value of certifications and degrees.


The OP was brutally honest that this is an academic assignment, even if 
what was being asked of us was unclear!

I wouldn't like to suggest that the OP thought us a 'paper mill' for 
ComSc, but the post is exactly how one might present to such. (the 
expected response being a $quotation for the work)


All of which may help to explain (if you are sometimes mystified by an 
apparent, and yet uncharacteristic, lack of 'helpfulness') why some of 
us *deliberately* avoid giving a direct answer to some posts. Instead, 
we will point to references where learning should take-place - and thus 
the *actual objective* be achieved. ("Socratic approach", 'engendering 
curiosity', blah, blah, psychology...)
-- 
Regards =dn

From alan.gauld at yahoo.co.uk  Sun Jun 14 19:29:36 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 15 Jun 2020 00:29:36 +0100
Subject: [Tutor] python
In-Reply-To: <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info>
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
 <1218488951.459090.1592136570249@mail.yahoo.com>
 <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info>
Message-ID: <rc6bt0$32qe$1@ciao.gmane.io>

On 14/06/2020 21:49, DL Neil via Tutor wrote:
> there are also 'services', often known as "paper mills" or "term paper 
> writing services", which offer to complete academic works - in exchange 
> for money. 

I can't pretend to begin to understand the rationale for
using such a service.

Does such a student expect to get a job after qualifying? If they
can't even do the near trivial assignments given out in
school/college how do they expect to do a job in the real
world with real problems?

Such a service would never have succeeded in my time at school,
students were in perpetual penury and could never afford to
employ such a thing! Of course that was before "student loans"
became a thing... :-/

-- 
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 oscar.j.benjamin at gmail.com  Sun Jun 14 20:09:04 2020
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 15 Jun 2020 01:09:04 +0100
Subject: [Tutor] python
In-Reply-To: <rc6bt0$32qe$1@ciao.gmane.io>
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
 <1218488951.459090.1592136570249@mail.yahoo.com>
 <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info>
 <rc6bt0$32qe$1@ciao.gmane.io>
Message-ID: <CAHVvXxSE6VmCDdSv6eOq-6qEWgw=k4bAUFMb9bdb-PLaEw-R2w@mail.gmail.com>

On Mon, 15 Jun 2020 at 00:30, Alan Gauld via Tutor <tutor at python.org> wrote:
>
> On 14/06/2020 21:49, DL Neil via Tutor wrote:
> > there are also 'services', often known as "paper mills" or "term paper
> > writing services", which offer to complete academic works - in exchange
> > for money.
>
> I can't pretend to begin to understand the rationale for
> using such a service.

Speaking as someone who teaches introductory programming to
undergraduate Engineering students I've seen this happen and in my
experience it comes more from desperation then calm rational thinking.

> Does such a student expect to get a job after qualifying? If they
> can't even do the near trivial assignments given out in
> school/college how do they expect to do a job in the real
> world with real problems?

Our students after graduating (as Engineers) will go on to do many
different things. Some of them will become professional programmers
and many more will be able to make use of their programming skills but
most will not really do any programming after graduating. We hope they
learned something from the experience of programming even if it
doesn't become a core part of their future career. I can see though
that some students think that programming units are just a hoop that
they might successfully go round rather than jump through.

> Such a service would never have succeeded in my time at school,
> students were in perpetual penury and could never afford to
> employ such a thing! Of course that was before "student loans"
> became a thing... :-/

There is significant variability in the wealth of students. There are
plenty enough who can afford to pay for these kinds of services that
it is clearly a viable business for those offering the services.
Whether it's viable for the customers is a different question:
generally the cases I know of do not lead ultimately to academic
success (i.e. graduation). Unfortunately I can't speak for the cases I
*don't* know of...

--
Oscar

From PyTutor at danceswithmice.info  Sun Jun 14 20:11:37 2020
From: PyTutor at danceswithmice.info (dn)
Date: Mon, 15 Jun 2020 12:11:37 +1200
Subject: [Tutor] python
In-Reply-To: <rc6bt0$32qe$1@ciao.gmane.io>
References: <1218488951.459090.1592136570249.ref@mail.yahoo.com>
 <1218488951.459090.1592136570249@mail.yahoo.com>
 <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info>
 <rc6bt0$32qe$1@ciao.gmane.io>
Message-ID: <453d29e7-2036-c419-4558-41929363d390@DancesWithMice.info>

On 15/06/20 11:29 AM, Alan Gauld via Tutor wrote:
> On 14/06/2020 21:49, DL Neil via Tutor wrote:
>> there are also 'services', often known as "paper mills" or "term paper
>> writing services", which offer to complete academic works - in exchange
>> for money.
> 
> I can't pretend to begin to understand the rationale for
> using such a service.
> 
> Does such a student expect to get a job after qualifying? If they
> can't even do the near trivial assignments given out in
> school/college how do they expect to do a job in the real
> world with real problems?
> 
> Such a service would never have succeeded in my time at school,
> students were in perpetual penury and could never afford to
> employ such a thing! Of course that was before "student loans"
> became a thing... :-/


The rationale is actually quite evident: when one arrives at university 
(or...), it doesn't take long to discover that there are some (other) 
extremely intelligent folk who might well be 'better' than you are. 
Plus, there are the usual 'pressures' of "time" and total-disasters when 
it comes to the skill of making the best use of one's time.

Another is 'competition' and the pressures of "continuous assessment" 
(numbers of tests/contributors to the final grade throughout the course) 
cf the once-uniform 'it all comes down to the final-exam' 
course-approach. Accordingly, one can't have 'an off-day' because every 
piece of work 'counts'. (sort of like paid-employment then!)

Accordingly, the temptation of finding any 'short-cut'.


You have touched-upon one of the reasons why I prefer the (old) 
technical institute/polytechnic/community college approach to *training* 
as opposed to the university approach to *education*. (if you don't 
understand the significance or subtlety of this comment, prepend "sex" 
to those two words and consider if they are 'the same'!) Unlike 
yourself, I do not teach/train Python, but do other languages and 
tech-skills. We both want to see employable 'graduates', either as 
trainer or as employer.

What we are seeking is "Mastery". Can the person (now) *do* the 
job/task/write the program(me)? Do, or die!

Does a student, faced with a likely 'fail' think about his/her future 
employment - or is (s)he all-consumed by securing a (good) pass for the 
current assignment?


Don't get me started on the economic fallacies of 'student loans'!

You must have been 'a good, little, boy'. Such services were very much 
available (in a different form) when we were at-school (walking miles 
each-way, no shoes, knee-high snow, fearful of attacks by dinosaurs...). 
There were always seniors/post-grads, etc, who were keen to 'make a 
quid/buck'. However, their lives were very much more risky because the 
institution could easily detect what was a-foot AND could reach-out and 
grab the miscreants for suitable punishment. These days, the student and 
'ghost-writer' could be continents apart - and far from the reach of 
'justice'!

My first job at the university was as a marker (grader, these days 
perhaps "teaching assistant"). After a date-due, I would receive 
hundreds of multi-page printouts of COBOL or FORTRAN, and results. 
(could fill a small suit-case!) A few days later, I would return to the 
lecturer and drop multiple distinct piles on his desk. The 'good pile' 
was the distinct and passing efforts. The 'bad pile' was distinct but 
failing results. The other piles were all 'copies' - each member of the 
pile (and there were often dozens) were essentially identical - but the 
different piles of 'copies' were differently characteristic.

I was always grateful that I didn't have to (a) identify who was the 
original author whose work passed/failed, or (b) decide how to mark 
(grade) or punish such. He repeatedly gave me 'glowing recommendations' 
because of the revelation of my ability to 'see' such patterns (which 
habit one would expect from systems analysts and designers, so shouldn't 
be 'that' special!).

So, "nothing new under the sun" then!
-- 
Regards =dn

From jtarun960 at gmail.com  Sun Jun 14 23:01:02 2020
From: jtarun960 at gmail.com (Chirag Jain)
Date: Mon, 15 Jun 2020 08:31:02 +0530
Subject: [Tutor] i want a solution to my problem
Message-ID: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>

module 'sqlite300.sqlite3' has no attribute 'connect'
I m getting this error even if I had changed the name of the file what should I do to overcome this problem.
Thank you

Sent from Mail for Windows 10


From krishp52 at rocketmail.com  Sun Jun 14 21:34:31 2020
From: krishp52 at rocketmail.com (Krish P)
Date: Mon, 15 Jun 2020 01:34:31 +0000 (UTC)
Subject: [Tutor] Tutor Digest, Vol 196, Issue 28
In-Reply-To: <mailman.2516.1592179925.24730.tutor@python.org>
References: <mailman.2516.1592179925.24730.tutor@python.org>
Message-ID: <729354972.640706.1592184871457@mail.yahoo.com>

 Hi, thanks for your response.
I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file.
given is the code that I came up with:
def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB
? ? f = open("data.txt", "r")? ? print(f.read())
? ??main()

Waiting for your kind assistanceThanksKrish    On Monday, June 15, 2020, 12:13:14 PM GMT+12, <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: python (Alan Gauld)
? 2. Re: python (DL Neil)
? 3. Re: python (Alan Gauld)
? 4. Re: python (Oscar Benjamin)
? 5. Re: python (dn)


----------------------------------------------------------------------

Message: 1
Date: Sun, 14 Jun 2020 18:43:56 +0100
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Subject: Re: [Tutor] python
Message-ID: <rc5nkt$3mht$1 at ciao.gmane.io>
Content-Type: text/plain; charset=utf-8

On 14/06/2020 13:09, Krish P via Tutor wrote:
> ...your assignment specifications ...to create a program that will read all this data
> from the file and generate the Syracuse sequence for each 

> 2. Additionally, you have to write every one of these Syracuse sequence> into a file calledSyra.txt using your code.

It looks like you got a reasonable description of the problem to be
solved. How did you get on? Got any code yet? Does it work?
If so, well done!

If not, how would you like us to help?

What error messages do you get?
How close is the data out to what you expected?
What aspects of the assignment do you not understand?
Which OS are you using? Which python version?
Do you have programming experience in other languages?
Or are you a beginner?

The more you help us the more we can help you.

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




------------------------------

Message: 2
Date: Mon, 15 Jun 2020 08:49:41 +1200
From: DL Neil <PyTutor at danceswithmice.info>
To: tutor at python.org
Subject: Re: [Tutor] python
Message-ID: <2b2ed393-7001-1e06-0106-5860bca574f9 at DancesWithMice.info>
Content-Type: text/plain; charset=utf-8; format=flowed

On 15/06/20 12:09 AM, Krish P via Tutor wrote:
> The Syracuse (also called the Collatz Hailstone) sequence...
> Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications...


In case you have not met "Moodle" before, it is an LMS (Learning 
Management System). It can be thought-of as a Content Management System 
with add-ons specifically designed for training, eg presenting lectures 
and papers, references, quizzes and exams, and so-forth. Think of it as 
the on-line equivalent of the binders of 'stuff' we used to accumulate 
as the academic year progressed (or the teacher's equivalent thereof).


Something else, of which you may be unaware: Another characteristic of 
today's education is that as well as the on-line teaching materials, 
there are also 'services', often known as "paper mills" or "term paper 
writing services", which offer to complete academic works - in exchange 
for money. Surprise, shock, horror! Thus, plagiarism and other enablers 
of 'cognitive by-pass learning' have exploded into a massive problem and 
dilute the value of certifications and degrees.


The OP was brutally honest that this is an academic assignment, even if 
what was being asked of us was unclear!

I wouldn't like to suggest that the OP thought us a 'paper mill' for 
ComSc, but the post is exactly how one might present to such. (the 
expected response being a $quotation for the work)


All of which may help to explain (if you are sometimes mystified by an 
apparent, and yet uncharacteristic, lack of 'helpfulness') why some of 
us *deliberately* avoid giving a direct answer to some posts. Instead, 
we will point to references where learning should take-place - and thus 
the *actual objective* be achieved. ("Socratic approach", 'engendering 
curiosity', blah, blah, psychology...)
-- 
Regards =dn


------------------------------

Message: 3
Date: Mon, 15 Jun 2020 00:29:36 +0100
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Subject: Re: [Tutor] python
Message-ID: <rc6bt0$32qe$1 at ciao.gmane.io>
Content-Type: text/plain; charset=utf-8

On 14/06/2020 21:49, DL Neil via Tutor wrote:
> there are also 'services', often known as "paper mills" or "term paper 
> writing services", which offer to complete academic works - in exchange 
> for money. 

I can't pretend to begin to understand the rationale for
using such a service.

Does such a student expect to get a job after qualifying? If they
can't even do the near trivial assignments given out in
school/college how do they expect to do a job in the real
world with real problems?

Such a service would never have succeeded in my time at school,
students were in perpetual penury and could never afford to
employ such a thing! Of course that was before "student loans"
became a thing... :-/

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




------------------------------

Message: 4
Date: Mon, 15 Jun 2020 01:09:04 +0100
From: Oscar Benjamin <oscar.j.benjamin at gmail.com>
To: Alan Gauld <alan.gauld at yahoo.co.uk>
Cc: tutor <tutor at python.org>
Subject: Re: [Tutor] python
Message-ID:
??? <CAHVvXxSE6VmCDdSv6eOq-6qEWgw=k4bAUFMb9bdb-PLaEw-R2w at mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"

On Mon, 15 Jun 2020 at 00:30, Alan Gauld via Tutor <tutor at python.org> wrote:
>
> On 14/06/2020 21:49, DL Neil via Tutor wrote:
> > there are also 'services', often known as "paper mills" or "term paper
> > writing services", which offer to complete academic works - in exchange
> > for money.
>
> I can't pretend to begin to understand the rationale for
> using such a service.

Speaking as someone who teaches introductory programming to
undergraduate Engineering students I've seen this happen and in my
experience it comes more from desperation then calm rational thinking.

> Does such a student expect to get a job after qualifying? If they
> can't even do the near trivial assignments given out in
> school/college how do they expect to do a job in the real
> world with real problems?

Our students after graduating (as Engineers) will go on to do many
different things. Some of them will become professional programmers
and many more will be able to make use of their programming skills but
most will not really do any programming after graduating. We hope they
learned something from the experience of programming even if it
doesn't become a core part of their future career. I can see though
that some students think that programming units are just a hoop that
they might successfully go round rather than jump through.

> Such a service would never have succeeded in my time at school,
> students were in perpetual penury and could never afford to
> employ such a thing! Of course that was before "student loans"
> became a thing... :-/

There is significant variability in the wealth of students. There are
plenty enough who can afford to pay for these kinds of services that
it is clearly a viable business for those offering the services.
Whether it's viable for the customers is a different question:
generally the cases I know of do not lead ultimately to academic
success (i.e. graduation). Unfortunately I can't speak for the cases I
*don't* know of...

--
Oscar


------------------------------

Message: 5
Date: Mon, 15 Jun 2020 12:11:37 +1200
From: dn <PyTutor at danceswithmice.info>
To: tutor at python.org
Subject: Re: [Tutor] python
Message-ID: <453d29e7-2036-c419-4558-41929363d390 at DancesWithMice.info>
Content-Type: text/plain; charset=utf-8; format=flowed

On 15/06/20 11:29 AM, Alan Gauld via Tutor wrote:
> On 14/06/2020 21:49, DL Neil via Tutor wrote:
>> there are also 'services', often known as "paper mills" or "term paper
>> writing services", which offer to complete academic works - in exchange
>> for money.
> 
> I can't pretend to begin to understand the rationale for
> using such a service.
> 
> Does such a student expect to get a job after qualifying? If they
> can't even do the near trivial assignments given out in
> school/college how do they expect to do a job in the real
> world with real problems?
> 
> Such a service would never have succeeded in my time at school,
> students were in perpetual penury and could never afford to
> employ such a thing! Of course that was before "student loans"
> became a thing... :-/


The rationale is actually quite evident: when one arrives at university 
(or...), it doesn't take long to discover that there are some (other) 
extremely intelligent folk who might well be 'better' than you are. 
Plus, there are the usual 'pressures' of "time" and total-disasters when 
it comes to the skill of making the best use of one's time.

Another is 'competition' and the pressures of "continuous assessment" 
(numbers of tests/contributors to the final grade throughout the course) 
cf the once-uniform 'it all comes down to the final-exam' 
course-approach. Accordingly, one can't have 'an off-day' because every 
piece of work 'counts'. (sort of like paid-employment then!)

Accordingly, the temptation of finding any 'short-cut'.


You have touched-upon one of the reasons why I prefer the (old) 
technical institute/polytechnic/community college approach to *training* 
as opposed to the university approach to *education*. (if you don't 
understand the significance or subtlety of this comment, prepend "sex" 
to those two words and consider if they are 'the same'!) Unlike 
yourself, I do not teach/train Python, but do other languages and 
tech-skills. We both want to see employable 'graduates', either as 
trainer or as employer.

What we are seeking is "Mastery". Can the person (now) *do* the 
job/task/write the program(me)? Do, or die!

Does a student, faced with a likely 'fail' think about his/her future 
employment - or is (s)he all-consumed by securing a (good) pass for the 
current assignment?


Don't get me started on the economic fallacies of 'student loans'!

You must have been 'a good, little, boy'. Such services were very much 
available (in a different form) when we were at-school (walking miles 
each-way, no shoes, knee-high snow, fearful of attacks by dinosaurs...). 
There were always seniors/post-grads, etc, who were keen to 'make a 
quid/buck'. However, their lives were very much more risky because the 
institution could easily detect what was a-foot AND could reach-out and 
grab the miscreants for suitable punishment. These days, the student and 
'ghost-writer' could be continents apart - and far from the reach of 
'justice'!

My first job at the university was as a marker (grader, these days 
perhaps "teaching assistant"). After a date-due, I would receive 
hundreds of multi-page printouts of COBOL or FORTRAN, and results. 
(could fill a small suit-case!) A few days later, I would return to the 
lecturer and drop multiple distinct piles on his desk. The 'good pile' 
was the distinct and passing efforts. The 'bad pile' was distinct but 
failing results. The other piles were all 'copies' - each member of the 
pile (and there were often dozens) were essentially identical - but the 
different piles of 'copies' were differently characteristic.

I was always grateful that I didn't have to (a) identify who was the 
original author whose work passed/failed, or (b) decide how to mark 
(grade) or punish such. He repeatedly gave me 'glowing recommendations' 
because of the revelation of my ability to 'see' such patterns (which 
habit one would expect from systems analysts and designers, so shouldn't 
be 'that' special!).

So, "nothing new under the sun" then!
-- 
Regards =dn


------------------------------

Subject: Digest Footer

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


------------------------------

End of Tutor Digest, Vol 196, Issue 28
**************************************
  

From deepakdixit0001 at gmail.com  Mon Jun 15 04:13:28 2020
From: deepakdixit0001 at gmail.com (Deepak Dixit)
Date: Mon, 15 Jun 2020 13:43:28 +0530
Subject: [Tutor] i want a solution to my problem
In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
Message-ID: <CAPmM==YK0mhZZyVsdZ+ky6uWuraCyQYvDagLa=e7tsvEHqYBsw@mail.gmail.com>

Chirag,

Add your connection code here with version details of OS, Python, sqlite
library then only someone will be able to guide you about the issue.

On Mon, Jun 15, 2020 at 1:25 PM Chirag Jain <jtarun960 at gmail.com> wrote:

> module 'sqlite300.sqlite3' has no attribute 'connect'
> I m getting this error even if I had changed the name of the file what
> should I do to overcome this problem.
> Thank you
>
> Sent from Mail for Windows 10
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>


-- 


*With Regards,*
*Deepak Kumar Dixit*

From alan.gauld at yahoo.co.uk  Mon Jun 15 07:03:27 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 15 Jun 2020 12:03:27 +0100
Subject: [Tutor] i want a solution to my problem
In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
Message-ID: <rc7khv$2nmu$1@ciao.gmane.io>

On 15/06/2020 04:01, Chirag Jain wrote:
> module 'sqlite300.sqlite3' has no attribute 'connect'

What is the sqlite300 thing? A google search didn't
show anything about it.

And why are you using that rather than the sqlite3
module that is part of the standard library?

We need some more background and especially some
code plus the full error text not just a summary.
OS and python versions 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 alan.gauld at yahoo.co.uk  Mon Jun 15 07:16:04 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 15 Jun 2020 12:16:04 +0100
Subject: [Tutor] Tutor Digest, Vol 196, Issue 28
In-Reply-To: <729354972.640706.1592184871457@mail.yahoo.com>
References: <mailman.2516.1592179925.24730.tutor@python.org>
 <729354972.640706.1592184871457@mail.yahoo.com>
Message-ID: <rc7l9k$dql$1@ciao.gmane.io>

On 15/06/2020 02:34, Krish P via Tutor wrote:
>  Hi, thanks for your response.
> I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file.
> given is the code that I came up with:
> def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB
> ? ? f = open("data.txt", "r")? ? print(f.read())
> ? ??main()

You need to post in plain text or the mail server screws up the
indentation as above.

However, even with that I have some questions:

main() isn't really a main function it just prints a banner message,
so calling it print_banner() or somesuch would make more sense.

Where is the code that reads each number (or even a single number!)
from the data file? the f.read() call will read the whole file into
a string but after you print it it disappears because you don't
store it anywhere.

I would expect your code structure to look like:

print banner
open and read data file
for each entry in data
   call syr() function on each data entry
   store and print result

If you don't know how to do any of that let us know.

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 david at graniteweb.com  Mon Jun 15 09:34:23 2020
From: david at graniteweb.com (David Rock)
Date: Mon, 15 Jun 2020 08:34:23 -0500
Subject: [Tutor] i want a solution to my problem
In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com>
Message-ID: <20200615133423.GA29904@apple.graniteweb.com>

* Chirag Jain <jtarun960 at gmail.com> [2020-06-15 08:31]:
> module 'sqlite300.sqlite3' has no attribute 'connect'

As others have mentioned, we need more information/code to give an accurate
assessment, but that particular message essentially means you have tried to use
the following in some way:

sqlite300.sqlite.connect

and "connect" is not something contained in sqlite300.sqlite3, so it
fails.  A sample of your code using the above statement will help a lot
in our understanding.

You will need to look at the documentation of the module you are using
(preferably with a link so we can look at it, too), or give us a full
traceback (not just the last line of error) for us to guide further.

-- 
David Rock
david at graniteweb.com

From john at johnweller.co.uk  Mon Jun 15 10:21:48 2020
From: john at johnweller.co.uk (John Weller)
Date: Mon, 15 Jun 2020 15:21:48 +0100
Subject: [Tutor] Advice Please
Message-ID: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>

I seek advice.  I am writing an application to control the humidity in a building.  I am new to Python but not programming.  I have an external class provided by the hardware supplier which will access the hardware to obtain the temperature and humidity.  I will create an instance of the class in the main part of the program then use it in a loop to get the data, process it and display it.  Accessing the data and checking it will be done in a function which I want to return the two values and an error count.  In the languages I am used to I would pass the parameters to the function by reference so as to be able to access the values outside the function however I understand that this is not available in Python.  Can Python return multiple values, (return temperature, humidity)?  If not I could make the variables global (not recommended but as these values are fundamental to the whole program then perhaps acceptable) or use a compound data structure such as a dictionary or create a class just to hold the data?  My question is ? what do you recommend?

 

Can anyone recommend a book that I can use as a reference to perhaps answer some question without having to bother you guys ?.  I?ve looked at a few books but they all have failings ? most I have seen don?t have an index (essential) or their code examples are screenshots from Terminal with coloured text on a black background which I find difficult to read or their style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort of thing.  A bit like the Three Bears, something not too technical but not too easy.  ?

 

TIA

 

John

 

John Weller

01380 723235

07976 393631

 


From joel.goldstick at gmail.com  Mon Jun 15 16:19:56 2020
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 15 Jun 2020 16:19:56 -0400
Subject: [Tutor] Advice Please
In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
Message-ID: <CAPM-O+zR7EGB7u19+Au9ii0SytjhcEQXTKZVA+iR+CBfmGYKEQ@mail.gmail.com>

On Mon, Jun 15, 2020 at 4:10 PM John Weller <john at johnweller.co.uk> wrote:

> I seek advice.  I am writing an application to control the humidity in a
> building.  I am new to Python but not programming.  I have an external
> class provided by the hardware supplier which will access the hardware to
> obtain the temperature and humidity.  I will create an instance of the
> class in the main part of the program then use it in a loop to get the
> data, process it and display it.  Accessing the data and checking it will
> be done in a function which I want to return the two values and an error
> count.  In the languages I am used to I would pass the parameters to the
> function by reference so as to be able to access the values outside the
> function however I understand that this is not available in Python.  Can
> Python return multiple values, (return temperature, humidity)?  If not I
> could make the variables global (not recommended but as these values are
> fundamental to the whole program then perhaps acceptable) or use a compound
> data structure such as a dictionary or create a class just to hold the
> data?  My question is ? what do you recommend?
>
>
> python can return multiple values:

>>> def myfunc():
...   a = 5
...   b = 1
...   return a, b
...
>>> print (myfunc())
(5, 1)
>>>

In this case python returns a tuple.

you could also do something like

x, y = myfunc()

print(x, y)



> Can anyone recommend a book that I can use as a reference to perhaps
> answer some question without having to bother you guys ?.  I?ve looked at
> a few books but they all have failings ? most I have seen don?t have an
> index (essential) or their code examples are screenshots from Terminal with
> coloured text on a black background which I find difficult to read or their
> style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort
> of thing.  A bit like the Three Bears, something not too technical but not
> too easy.  ?
>
>
>
> TIA
>
>
>
> John
>
>
>
> John Weller
>
> 01380 723235
>
> 07976 393631
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>


-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays

From david at graniteweb.com  Mon Jun 15 16:23:30 2020
From: david at graniteweb.com (David Rock)
Date: Mon, 15 Jun 2020 15:23:30 -0500
Subject: [Tutor] Advice Please
In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
Message-ID: <20200615202330.GF29904@apple.graniteweb.com>

* John Weller <john at johnweller.co.uk> [2020-06-15 15:21]:
> pass the parameters to the function by reference so as to be able to
> access the values outside the function however I understand that this
> is not available in Python.  Can Python return multiple values,
> (return temperature, humidity)?  If not I could make the variables

yes, it's possible to return multiple values

temp, humidity = read_temp_humidity()

Where the return statement within your function will look like:

return temp, humidity

> global (not recommended but as these values are fundamental to the
> whole program then perhaps acceptable) or use a compound data
> structure such as a dictionary or create a class just to hold the
> data?  My question is ? what do you recommend?

Globals or returning a single dictionary would also work.  Generally, I
use a dict if there are going to be many element to return, and a tuple
if only a few (eg, just temp and humidity as above).

> Can anyone recommend a book that I can use as a reference to perhaps
> answer some question without having to bother you guys ?.  I?ve

That's hard to do without more of a solid understanding of your tastes
and needs.  There's the Python Books list on python.org
https://wiki.python.org/moin/PythonBooks


There are several good web-based "books" as well "Dive Into Python"
usually bubbles to the top:  https://diveintopython3.net/

I honestly do most of my stuff searching within the online docs.

-- 
David Rock
david at graniteweb.com

From stephen.m.smith at comcast.net  Mon Jun 15 16:29:02 2020
From: stephen.m.smith at comcast.net (stephen.m.smith at comcast.net)
Date: Mon, 15 Jun 2020 16:29:02 -0400
Subject: [Tutor] Advice Please
In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
Message-ID: <00e701d64353$9c2fc050$d48f40f0$@comcast.net>

Pretty easy to do if I understand your question.

https://note.nkmk.me/en/python-function-return-multiple-values/

or

https://www.geeksforgeeks.org/g-fact-41-multiple-return-values-in-python/

basically

	return (temperature, humidity)

or

	return temperature, humidity

Positional integrity maintained.

-----Original Message-----
From: Tutor <tutor-bounces+stephen.m.smith=comcast.net at python.org> On Behalf Of John Weller
Sent: Monday, June 15, 2020 10:22 AM
To: tutor at python.org
Subject: [Tutor] Advice Please

I seek advice.  I am writing an application to control the humidity in a building.  I am new to Python but not programming.  I have an external class provided by the hardware supplier which will access the hardware to obtain the temperature and humidity.  I will create an instance of the class in the main part of the program then use it in a loop to get the data, process it and display it.  Accessing the data and checking it will be done in a function which I want to return the two values and an error count.  In the languages I am used to I would pass the parameters to the function by reference so as to be able to access the values outside the function however I understand that this is not available in Python.  Can Python return multiple values, (return temperature, humidity)?  If not I could make the variables global (not recommended but as these values are fundamental to the whole program then perhaps acceptable) or use a compound data structure such as a dictionary or create a class just to hold the data?  My question is ? what do you recommend?

 

Can anyone recommend a book that I can use as a reference to perhaps answer some question without having to bother you guys ?.  I?ve looked at a few books but they all have failings ? most I have seen don?t have an index (essential) or their code examples are screenshots from Terminal with coloured text on a black background which I find difficult to read or their style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort of thing.  A bit like the Three Bears, something not too technical but not too easy.  ?

 

TIA

 

John

 

John Weller

01380 723235

07976 393631

 

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


From krishp52 at rocketmail.com  Mon Jun 15 23:22:54 2020
From: krishp52 at rocketmail.com (Krish P)
Date: Tue, 16 Jun 2020 03:22:54 +0000 (UTC)
Subject: [Tutor] Tutor Digest, Vol 196, Issue 30
In-Reply-To: <mailman.9.1592236801.20881.tutor@python.org>
References: <mailman.9.1592236801.20881.tutor@python.org>
Message-ID: <1024482361.1161186.1592277774873@mail.yahoo.com>

 please check the code, I am finding it difficult to open the data file to read data from it and then finding the Syracuse sequence
Please see the data and code attached
    On Tuesday, June 16, 2020, 04:00:22 AM GMT+12, tutor-request at python.org <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 196, Issue 28 (Alan Gauld)
? 2. Re: i want a solution to my problem (David Rock)


----------------------------------------------------------------------

Message: 1
Date: Mon, 15 Jun 2020 12:16:04 +0100
From: Alan Gauld <alan.gauld at yahoo.co.uk>
To: tutor at python.org
Subject: Re: [Tutor] Tutor Digest, Vol 196, Issue 28
Message-ID: <rc7l9k$dql$1 at ciao.gmane.io>
Content-Type: text/plain; charset=utf-8

On 15/06/2020 02:34, Krish P via Tutor wrote:
>? Hi, thanks for your response.
> I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file.
> given is the code that I came up with:
> def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB
> ? ? f = open("data.txt", "r")? ? print(f.read())
> ? ??main()

You need to post in plain text or the mail server screws up the
indentation as above.

However, even with that I have some questions:

main() isn't really a main function it just prints a banner message,
so calling it print_banner() or somesuch would make more sense.

Where is the code that reads each number (or even a single number!)
from the data file? the f.read() call will read the whole file into
a string but after you print it it disappears because you don't
store it anywhere.

I would expect your code structure to look like:

print banner
open and read data file
for each entry in data
? call syr() function on each data entry
? store and print result

If you don't know how to do any of that let us know.

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




------------------------------

Message: 2
Date: Mon, 15 Jun 2020 08:34:23 -0500
From: David Rock <david at graniteweb.com>
To: tutor at python.org
Subject: Re: [Tutor] i want a solution to my problem
Message-ID: <20200615133423.GA29904 at apple.graniteweb.com>
Content-Type: text/plain; charset=us-ascii

* Chirag Jain <jtarun960 at gmail.com> [2020-06-15 08:31]:
> module 'sqlite300.sqlite3' has no attribute 'connect'

As others have mentioned, we need more information/code to give an accurate
assessment, but that particular message essentially means you have tried to use
the following in some way:

sqlite300.sqlite.connect

and "connect" is not something contained in sqlite300.sqlite3, so it
fails.? A sample of your code using the above statement will help a lot
in our understanding.

You will need to look at the documentation of the module you are using
(preferably with a link so we can look at it, too), or give us a full
traceback (not just the last line of error) for us to guide further.

-- 
David Rock
david at graniteweb.com


------------------------------

Subject: Digest Footer

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


------------------------------

End of Tutor Digest, Vol 196, Issue 30
**************************************
  
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: data.txt
URL: <http://mail.python.org/pipermail/tutor/attachments/20200616/764a7529/attachment-0001.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Assign3_S11048116.py
URL: <http://mail.python.org/pipermail/tutor/attachments/20200616/764a7529/attachment-0001.ksh>

From alan.gauld at yahoo.co.uk  Tue Jun 16 04:05:51 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 16 Jun 2020 09:05:51 +0100
Subject: [Tutor] Tutor Digest, Vol 196, Issue 30
In-Reply-To: <1024482361.1161186.1592277774873@mail.yahoo.com>
References: <mailman.9.1592236801.20881.tutor@python.org>
 <1024482361.1161186.1592277774873@mail.yahoo.com>
Message-ID: <rc9ugv$79u$1@ciao.gmane.io>

First, please do not send the entire digest. We have all seen these
messages already and some people pay for their data by the byte.

Also it is better to send code in-line (using plain text format)
since the server strips attachments which it deems security threats.

On 16/06/2020 04:22, Krish P via Tutor wrote:
>  please check the code, I am finding it difficult to open the data file to read data from it 

The code is a syr() function that should work.
But it makes no attempt to open a file, read
the contents or process the data.

The previous program code opened the file and printed it.
You need to store the data and split it into its
constituent numbers.

But we can only help you fix code that we can see.
It's impossible to guess what you are doing wrong if
we can't see the code that is broken.

I've included your function below for the archive.

#################################
def printCollatz(x):

    # We simply follow steps
    # while we do not reach 1

    while x != 1:
        print(x, end = ' ')

        # If x is odd
        if x & 1:
            x = 3 * x + 1

        # If even
        else:
            x = x // 2

    # Print 1 at the end
    print(x)
##############################

-- 
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 btinternet.com  Mon Jun  8 20:12:26 2020
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 9 Jun 2020 01:12:26 +0100
Subject: [Tutor] What are the benefits of template or abstract base
 classes?
In-Reply-To: <CANDiX9J2F2xjN33W0np-ixm5=NUxNkR8z5WeASX8zj+Q-RzGXQ@mail.gmail.com>
References: <20200608030250.GF10604@Dream-Machine1>
 <rbllgs$2vau$1@ciao.gmane.io>
 <CANDiX9J2F2xjN33W0np-ixm5=NUxNkR8z5WeASX8zj+Q-RzGXQ@mail.gmail.com>
Message-ID: <1af601fb-89f3-2f66-ece5-98c0efd6e6eb@btinternet.com>

On 08/06/2020 19:00, boB Stepp wrote:

> I did receive the original email prior to it appearing on the Tutor Archive.

Glad it went somewhere. It certainly never showed up on the list!

> Hmm.  Then ABCs seem quite useful.  I wonder why I normally only see
> mention of them as being advanced features?  

I guess because the vast majority of folks using classes don't
really build OOP programs, they build procedural programs
that use classes and objects as "smart data". And thats how many
beginner tutorials (including mine) teach it.

But if you read some of the more advanced OOP and especially OOD
books/tutorials you will see a lot more on using ABC/virtual classes.
A good example of one such is Grady Booch's book.

> they would seem very useful for anything beyond small, simple OO
> programs.  

Definitely more useful when you get to something with, say,
double-digit number of classes. I'd say at least 4 or 5 to make much
sense of it.

> ...with mixins its normally a case
>> of partially implemented classes rather than pure abstracts
>>  - what C++ calls virtual classes.
> 
> So these concepts are language-agnostic and broadly used?

Absolutely. They are a fundamental part of the OOP paradigm.
Almost all OOD techniques work along the lines of:

0) identify requirements as a set of use cases and user stories
1) identify classes and responsibilities
2) identify is-a commonality between classes and represent
   generalized versions as ABC (Person, Shape, Network,
   Form, Request, transaction, etc)
3) create a high level framework solving the problem
   using only the ABCs. (include has-a and uses relationships)
4) build sufficient concrete classes to test the framework
   with 1 scenario/story
5) build more concrete classes, test another scenario or story.
6) repeat 5 until done.

-- 
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 john at johnweller.co.uk  Tue Jun 16 04:04:21 2020
From: john at johnweller.co.uk (John Weller)
Date: Tue, 16 Jun 2020 09:04:21 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <20200615202330.GF29904@apple.graniteweb.com>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <20200615202330.GF29904@apple.graniteweb.com>
Message-ID: <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk>

Many thanks to all who replied - problem solved!!

John

John Weller
01380 723235
07976 393631

-----Original Message-----
From: Tutor <tutor-bounces+john=johnweller.co.uk at python.org> On Behalf Of David Rock
Sent: 15 June 2020 21:24
To: tutor at python.org
Subject: Re: [Tutor] Advice Please

* John Weller <john at johnweller.co.uk> [2020-06-15 15:21]:
> pass the parameters to the function by reference so as to be able to 
> access the values outside the function however I understand that this 
> is not available in Python.  Can Python return multiple values, 
> (return temperature, humidity)?  If not I could make the variables

yes, it's possible to return multiple values

temp, humidity = read_temp_humidity()

Where the return statement within your function will look like:

return temp, humidity

> global (not recommended but as these values are fundamental to the 
> whole program then perhaps acceptable) or use a compound data 
> structure such as a dictionary or create a class just to hold the 
> data?  My question is ? what do you recommend?

Globals or returning a single dictionary would also work.  Generally, I use a dict if there are going to be many element to return, and a tuple if only a few (eg, just temp and humidity as above).

> Can anyone recommend a book that I can use as a reference to perhaps 
> answer some question without having to bother you guys ?.  I?ve

That's hard to do without more of a solid understanding of your tastes and needs.  There's the Python Books list on python.org https://wiki.python.org/moin/PythonBooks


There are several good web-based "books" as well "Dive Into Python"
usually bubbles to the top:  https://diveintopython3.net/

I honestly do most of my stuff searching within the online docs.

--
David Rock
david at graniteweb.com
_______________________________________________
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 Jun 16 11:17:42 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 16 Jun 2020 16:17:42 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <20200615202330.GF29904@apple.graniteweb.com>
 <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk>
Message-ID: <rcanqn$3aco$1@ciao.gmane.io>

On 16/06/2020 09:04, John Weller wrote:
> Many thanks to all who replied - problem solved!!

Just one other point that i don;t think anyone else
picked up specifically.

>> pass the parameters to the function by reference so as to be able to 
>> access the values outside the function however I understand that this 
>> is not available in Python.  

Python is closer to pass by reference than it is to pass by value.
In python variables(and that includes function parameters) are
merely names that refer to objects. So a function parameter is
a name to which an object can be attached.

If that object is mutable (list, dict, class etc) you can change
it inside the function and the change will be apparent outside the
function too. If its immutable a new value will be created and
assigned to the parameter name but the original variable will
still refer to the original object.

Once you get used to that idea it all makes sense but for beginners
to the language it is quite different to how most languages work.

Here is an example:

def changeSeq(seq):
    seq[0] = 42   # mutable list
    return seq

lst = [1,2,3]
changeSeq(lst)
print(lst)  -> [42,2,3]


def changeVal(val):
    val = 42   # immutable integer
    return val

x = 66
changeVal(x)
print(x)  -> 66

Of course the cleanest way is always to reassign the
function return value. In both cases above:

lst = changeSeq(lst)   -> [42,2,3]
x = changeVal(x)       -> 42

This is not an expensive option since the objects are
not being copied, it is just a reassignment of the
reference in both cases.

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 david at graniteweb.com  Tue Jun 16 12:36:54 2020
From: david at graniteweb.com (David Rock)
Date: Tue, 16 Jun 2020 11:36:54 -0500
Subject: [Tutor] Advice Please
In-Reply-To: <rcanqn$3aco$1@ciao.gmane.io>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <20200615202330.GF29904@apple.graniteweb.com>
 <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk>
 <rcanqn$3aco$1@ciao.gmane.io>
Message-ID: <20200616163654.GC7284@apple.graniteweb.com>

* Alan Gauld via Tutor <tutor at python.org> [2020-06-16 16:17]:
> On 16/06/2020 09:04, John Weller wrote:
> > Many thanks to all who replied - problem solved!!
> 
> Python is closer to pass by reference than it is to pass by value.
> In python variables(and that includes function parameters) are
> merely names that refer to objects. So a function parameter is
> a name to which an object can be attached.
> 
> If that object is mutable (list, dict, class etc) you can change
> it inside the function and the change will be apparent outside the
> function too. If its immutable a new value will be created and
> assigned to the parameter name but the original variable will
> still refer to the original object.

That's a good callout, Alan.  There's a summary of the OP question in the FAQ, as well:

https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

-- 
David Rock
david at graniteweb.com

From annametreveli at gmail.com  Tue Jun 16 18:40:39 2020
From: annametreveli at gmail.com (Anna Metreveli)
Date: Wed, 17 Jun 2020 00:40:39 +0200
Subject: [Tutor] help with twitter API
Message-ID: <CANFiP0o1Qe3UWtSpQVeU8q73xBdsVQpdLAcakpgMC-nM+0Wrmw@mail.gmail.com>

Hi, everyone

I'm doing a small study in sociolinguistics and currently struggling with
Twitter API. I want to collect tweets with animated GIFS. I tried using
filter: images when initializing Tweepy API:
API = tweepy.API(auth)
results = api.search(q=" filter:images", lang="en")
but I am out of ideas about how to sort out GIFs from that by using the
extended_enteties/media/type  with JSON where type is "animated_gif".

Thank you!

From PyTutor at danceswithmice.info  Tue Jun 16 19:32:04 2020
From: PyTutor at danceswithmice.info (dn)
Date: Wed, 17 Jun 2020 11:32:04 +1200
Subject: [Tutor] Advice Please
In-Reply-To: <rcanqn$3aco$1@ciao.gmane.io>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <20200615202330.GF29904@apple.graniteweb.com>
 <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk>
 <rcanqn$3aco$1@ciao.gmane.io>
Message-ID: <3ffd4250-9a09-4775-8db7-d06049a7555d@DancesWithMice.info>

On 17/06/20 3:17 AM, Alan Gauld via Tutor wrote:
> On 16/06/2020 09:04, John Weller wrote:
>> Many thanks to all who replied - problem solved!!
> 
> Just one other point that i don;t think anyone else
> picked up specifically.
> 
>>> pass the parameters to the function by reference so as to be able to
>>> access the values outside the function however I understand that this
>>> is not available in Python.
> 
> Python is closer to pass by reference than it is to pass by value.
> In python variables(and that includes function parameters) are
> merely names that refer to objects. So a function parameter is
> a name to which an object can be attached.
> 
> If that object is mutable (list, dict, class etc) you can change
> it inside the function and the change will be apparent outside the
> function too. If its immutable a new value will be created and
> assigned to the parameter name but the original variable will
> still refer to the original object.
> 
> Once you get used to that idea it all makes sense but for beginners
> to the language it is quite different to how most languages work.
> 
> Here is an example:
> 
> def changeSeq(seq):
>      seq[0] = 42   # mutable list
>      return seq
> 
> lst = [1,2,3]
> changeSeq(lst)
> print(lst)  -> [42,2,3]
> 
> 
> def changeVal(val):
>      val = 42   # immutable integer
>      return val
> 
> x = 66
> changeVal(x)
> print(x)  -> 66
> 
> Of course the cleanest way is always to reassign the
> function return value. In both cases above:
> 
> lst = changeSeq(lst)   -> [42,2,3]
> x = changeVal(x)       -> 42
> 
> This is not an expensive option since the objects are
> not being copied, it is just a reassignment of the
> reference in both cases.


Recommend playing with the Python Tutor (http://www.pythontutor.com/). 
If you try these (earlier) snippets, it enables one to step-through the 
code whilst showing stack-frames and illustrating "scope".

Some Python-editors offer a similar 'visual programming' experience.

The term "variable" (which most of us 'bandy around' quite happily) has 
a substantively different meaning in Python (than it does in other 
languages), eg a name in Python will point to a value, but a name may 
not point to another name, ie:

 >>> a = 1
 >>> b = a
 >>> a
1
 >>> b
1
 >>> a = 2
 >>> a
2
 >>> b
1

Similarly, when 'passing' data to a function, the parameters are 
separate names from the arguments. However, there is the major 
difference in behavior between mutable and immutable, which is 
frequently a major 'gotcha' for newcomers (per above). The illustration 
PythonTutor provides is a positive means of reinforcing this learning!

Thus, many 'traditional' discussions of "pass by reference"/"pass by 
value" no longer apply, because neither quite applies. They don't have a 
place within the Python model.
-- 
Regards =dn

From bouncingcats at gmail.com  Tue Jun 16 23:18:49 2020
From: bouncingcats at gmail.com (David)
Date: Wed, 17 Jun 2020 13:18:49 +1000
Subject: [Tutor] Advice Please
In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
Message-ID: <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>

On Tue, 16 Jun 2020 at 06:11, John Weller <john at johnweller.co.uk> wrote:

[...]  I am new to Python but not programming.  [...] In the languages I am
> used to I would pass the parameters to the function by reference [...] My
> question is ? what do you recommend?
>

Hi John,

In addition to the other replies, I strongly recommend you
watch "Facts and Myths about Python names and values" [1],
a presentation given at PyCon 2015 by Ned Batchelder, a
very well regarded educator in the Python community.

You can also search youtube for other presentations by Ned
or Raymond Hettinger, they will greatly improve your Python
insight beyond what you will find in the books and written
documentation.

Python is a beautiful language, but some of that beauty
requires insights to appreciate, and the official docs don't
do a great job of providing that in my experience.

[1] https://www.youtube.com/watch?v=_AEJHKGk9ns

From breamoreboy at gmail.com  Tue Jun 16 23:50:49 2020
From: breamoreboy at gmail.com (Mark Lawrence)
Date: Wed, 17 Jun 2020 04:50:49 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
Message-ID: <rcc3uq$1cjg$1@ciao.gmane.io>

On 17/06/2020 04:18, David wrote:
> On Tue, 16 Jun 2020 at 06:11, John Weller <john at johnweller.co.uk> wrote:
> 
> [...]  I am new to Python but not programming.  [...] In the languages I am
>> used to I would pass the parameters to the function by reference [...] My
>> question is ? what do you recommend?
>>
> 
> Hi John,
> 
> In addition to the other replies, I strongly recommend you
> watch "Facts and Myths about Python names and values" [1],
> a presentation given at PyCon 2015 by Ned Batchelder, a
> very well regarded educator in the Python community.
> 
> You can also search youtube for other presentations by Ned
> or Raymond Hettinger, they will greatly improve your Python
> insight beyond what you will find in the books and written
> documentation.
> 
> Python is a beautiful language, but some of that beauty
> requires insights to appreciate, and the official docs don't
> do a great job of providing that in my experience.
> 
> [1] https://www.youtube.com/watch?v=_AEJHKGk9ns

Another resource 
https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From john at johnweller.co.uk  Wed Jun 17 05:44:11 2020
From: john at johnweller.co.uk (John Weller)
Date: Wed, 17 Jun 2020 10:44:11 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <rcc3uq$1cjg$1@ciao.gmane.io>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
 <rcc3uq$1cjg$1@ciao.gmane.io>
Message-ID: <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>

Thanks guys for all your help and advice, I am constantly impressed by your obvious passion for the language and willingness to freely give of your time and expertise to help others.  I am also surprised by the large, sometimes overwhelming, amount of information available - my problem is finding it and then sorting the wheat from the chaff ?  I was first taught to program using a variant of Dartmouth Basic on a mainframe in 1976 as part of a postgraduate navigation course in the RAF.  I progressed through Algol, Fortran, Pascal, etc and earnt my living after I left the service with FoxPro.  I retired 15 years ago but earlier this year I bought a Raspberry Pi and an electronics kit which came with code in Python and C so I had to learn one of them.  I am now hooked on Python but seem to spend my time taking two steps forward then between one and three back!

Thanks again for all your help.

John

John Weller
01380 723235
07976 393631



From johnf at jfcomputer.com  Wed Jun 17 08:52:13 2020
From: johnf at jfcomputer.com (john)
Date: Wed, 17 Jun 2020 05:52:13 -0700
Subject: [Tutor] Advice Please
In-Reply-To: <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
 <rcc3uq$1cjg$1@ciao.gmane.io>
 <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>
Message-ID: <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com>

On 6/17/20 2:44 AM, John Weller wrote:
> Thanks guys for all your help and advice, I am constantly impressed by your obvious passion for the language and willingness to freely give of your time and expertise to help others.  I am also surprised by the large, sometimes overwhelming, amount of information available - my problem is finding it and then sorting the wheat from the chaff ?  I was first taught to program using a variant of Dartmouth Basic on a mainframe in 1976 as part of a postgraduate navigation course in the RAF.  I progressed through Algol, Fortran, Pascal, etc and earnt my living after I left the service with FoxPro.  I retired 15 years ago but earlier this year I bought a Raspberry Pi and an electronics kit which came with code in Python and C so I had to learn one of them.  I am now hooked on Python but seem to spend my time taking two steps forward then between one and three back!
>
> Thanks again for all your help.
>
> John
>
> John Weller
> 01380 723235
> 07976 393631
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
I noticed that you once used FoxPro.? You might want to checkout Dabo 
(https://dabodev.com/). Dabo is python's answer to foxpro.? It works in 
general with python 3.x and wxPython 4.x but some items are not working 
correctly.? I have been working on moving to the latest wxPython 4.1.x.? 
There are several branches on github (dabo3-4.1 is my branch).

git clone git at github.com:dabodev/dabo.git

Good luck,
Johnf


From alan.gauld at btinternet.com  Wed Jun 17 13:47:49 2020
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 17 Jun 2020 18:47:49 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
 <rcc3uq$1cjg$1@ciao.gmane.io>
 <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>
 <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com>
Message-ID: <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com>

On 17/06/2020 13:52, john wrote:

> I noticed that you once used FoxPro.? You might want to checkout Dabo 
> (https://dabodev.com/). Dabo is python's answer to foxpro.? 

I'm glad to hear Dabo is still going strong. A few years back I
investigated all the GUI builder tools I could find for python.
Dabo was one of the best. At that time it was tricky to make it work
with other databases but they had plans to fix that. But at the time i
needed SqlLite integration so I passed.

-- 
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 guroanne at gmail.com  Thu Jun 18 04:53:34 2020
From: guroanne at gmail.com (=?UTF-8?Q?Guro_Anne_Br=C3=A6kken?=)
Date: Thu, 18 Jun 2020 10:53:34 +0200
Subject: [Tutor] obspy.imaging.spectrogram
Message-ID: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>

Hi there,

Is there anyone out there who would know how to output the data from the
obspy function spectrogram (and not only an image file)?

Problem:
1.read in one seismic trace (SEGY format) - OK
2. calculate and plot the spectrogram using obspy.imaging.spectrogram - OK
3. output the image of the spectrogram as a PNG file - OK
4. output the data points in SEGY format - NOT POSSIBLE ??

My code is the following:
st=obspy.read(\seismic\trace.segy)
st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9,
outfile="st_spec_image")
st_spec.write('st_spec_data', format='SEGY')

I am running the code with Anaconda navigator and python 3.7.6

I hope this was clear. Looking forward to hearing about programmers'
experiences with this issue!

Kind regards,
Guro Anne Braekken

From alan.gauld at yahoo.co.uk  Thu Jun 18 05:35:05 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 18 Jun 2020 10:35:05 +0100
Subject: [Tutor] obspy.imaging.spectrogram
In-Reply-To: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>
References: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>
Message-ID: <rcfcg9$2vk7$1@ciao.gmane.io>

On 18/06/2020 09:53, Guro Anne Br?kken wrote:
> Hi there,
> 
> Is there anyone out there who would know how to output the data from the
> obspy function spectrogram (and not only an image file)?
> 

This is a pretty specialized question for a general group like tutor
especially since its not a standard library package.

I suggest reaching out to the folks on the SciPy forum, they are more
likely to include users of obspy. There is also an obspy mailing list:

http://lists.obspy.org/cgi-bin/mailman/listinfo/obspy-users

> My code is the following:

I hope not!

> st=obspy.read(\seismic\trace.segy)

The filename should be in quotes and, since you use
backslashes prepended with an 'r'

> st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9,
> outfile="st_spec_image")
> st_spec.write('st_spec_data', format='SEGY'

-- 
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 john at johnweller.co.uk  Thu Jun 18 07:09:52 2020
From: john at johnweller.co.uk (John Weller)
Date: Thu, 18 Jun 2020 12:09:52 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
Message-ID: <002601d64560$fea0b410$fbe21c30$@johnweller.co.uk>

Excellent video, explains a lot!  Interesting behaviour ?

Thanks

John

John Weller
01380 723235
07976 393631

-----Original Message-----
From: Tutor <tutor-bounces+john=johnweller.co.uk at python.org> On Behalf Of David
Sent: 17 June 2020 04:19
To: Python Tutor <tutor at python.org>
Subject: Re: [Tutor] Advice Please

On Tue, 16 Jun 2020 at 06:11, John Weller <john at johnweller.co.uk> wrote:

[...]  I am new to Python but not programming.  [...] In the languages I am
> used to I would pass the parameters to the function by reference [...] 
> My question is ? what do you recommend?
>

Hi John,

In addition to the other replies, I strongly recommend you watch "Facts and Myths about Python names and values" [1], a presentation given at PyCon 2015 by Ned Batchelder, a very well regarded educator in the Python community.

You can also search youtube for other presentations by Ned or Raymond Hettinger, they will greatly improve your Python insight beyond what you will find in the books and written documentation.

Python is a beautiful language, but some of that beauty requires insights to appreciate, and the official docs don't do a great job of providing that in my experience.

[1] https://www.youtube.com/watch?v=_AEJHKGk9ns
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


From john at johnweller.co.uk  Thu Jun 18 07:36:06 2020
From: john at johnweller.co.uk (John Weller)
Date: Thu, 18 Jun 2020 12:36:06 +0100
Subject: [Tutor] Advice Please
In-Reply-To: <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
 <rcc3uq$1cjg$1@ciao.gmane.io>
 <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>
 <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com>
 <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com>
Message-ID: <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk>

I didn't get John's original posting about Dabo (or maybe I lost it).  I was aware of Dabo as it was written by Ed Leafe who runs the ProFox email list which I have been a member of for over 20 years.  Profox is a very friendly, helpful list and I'm getting the same warm feeling about this one ?  I bought a Raspberry Pi and an electronics kit just before lockdown, did some Future Learn courses on Python and one on HTML, etc and have booked one on robotics - I have found so many options and paths I want to follow I'm spoilt for choice!

Regards  

John

John Weller
01380 723235
07976 393631

-----Original Message-----
From: Tutor <tutor-bounces+john=johnweller.co.uk at python.org> On Behalf Of Alan Gauld via Tutor
Sent: 17 June 2020 18:48
To: tutor at python.org
Cc: Alan Gauld <alan.gauld at btinternet.com>
Subject: Re: [Tutor] Advice Please

On 17/06/2020 13:52, john wrote:

> I noticed that you once used FoxPro.  You might want to checkout Dabo 
> (https://dabodev.com/). Dabo is python's answer to foxpro.

I'm glad to hear Dabo is still going strong. A few years back I investigated all the GUI builder tools I could find for python.
Dabo was one of the best. At that time it was tricky to make it work with other databases but they had plans to fix that. But at the time i needed SqlLite integration so I passed.

--
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 bouncingcats at gmail.com  Thu Jun 18 11:13:32 2020
From: bouncingcats at gmail.com (David)
Date: Fri, 19 Jun 2020 01:13:32 +1000
Subject: [Tutor] Advice Please
In-Reply-To: <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk>
References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk>
 <CAMPXz=q_czMF1OpAFhy006iw-cqce6BcbgtHAo_d9zt8aaNwVw@mail.gmail.com>
 <rcc3uq$1cjg$1@ciao.gmane.io>
 <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk>
 <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com>
 <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com>
 <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk>
Message-ID: <CAMPXz=pCb1SOQnk2nyFy44TdjFU8BA1JWPP2Eb5KfjM+SbE0ww@mail.gmail.com>

On Thu, 18 Jun 2020 at 23:00, John Weller <john at johnweller.co.uk> wrote:

I didn't get John's original posting about Dabo (or maybe I lost it).
>

You can read it here:
https://mail.python.org/pipermail/tutor/2020-June/116773.html

By the way, like many mailing lists, we prefer interleaved replies here
so please don't top-post, and please trim your replies, more info here:
https://en.wikipedia.org/wiki/Posting_style#Trimming_and_reformatting
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
https://en.wikipedia.org/wiki/Posting_style#Top-posting

Thanks!

From guroanne at gmail.com  Thu Jun 18 09:36:39 2020
From: guroanne at gmail.com (=?UTF-8?Q?Guro_Anne_Br=C3=A6kken?=)
Date: Thu, 18 Jun 2020 15:36:39 +0200
Subject: [Tutor] obspy.imaging.spectrogram
In-Reply-To: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>
References: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>
Message-ID: <CAKWHsQkScEvbRGt8JpGm3j02QrfUZtRC0a0aNQnrFo2Ek8DLYw@mail.gmail.com>

Hi Again,

Unfortunately I forgot to mention the error message, it is the following:

AttributeError                            Traceback (most recent call
last)<ipython-input-9-801c1ba52996> in <module>----> 1
st_spec.write('st_spec_data', format='SEGY')
AttributeError: 'list' object has no attribute 'write'

The object type is "list", which does not make any sense since I will need
floating point numbers.......

Kind regards,
Guro Anne Br?kken

On Thu, Jun 18, 2020 at 10:53 AM Guro Anne Br?kken <guroanne at gmail.com>
wrote:

> Hi there,
>
> Is there anyone out there who would know how to output the data from the
> obspy function spectrogram (and not only an image file)?
>
> Problem:
> 1.read in one seismic trace (SEGY format) - OK
> 2. calculate and plot the spectrogram using obspy.imaging.spectrogram - OK
> 3. output the image of the spectrogram as a PNG file - OK
> 4. output the data points in SEGY format - NOT POSSIBLE ??
>
> My code is the following:
> st=obspy.read(\seismic\trace.segy)
> st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9,
> outfile="st_spec_image")
> st_spec.write('st_spec_data', format='SEGY')
>
> I am running the code with Anaconda navigator and python 3.7.6
>
> I hope this was clear. Looking forward to hearing about programmers'
> experiences with this issue!
>
> Kind regards,
> Guro Anne Braekken
>
>
>

From alan.gauld at yahoo.co.uk  Thu Jun 18 13:07:41 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 18 Jun 2020 18:07:41 +0100
Subject: [Tutor] obspy.imaging.spectrogram
In-Reply-To: <CAKWHsQkScEvbRGt8JpGm3j02QrfUZtRC0a0aNQnrFo2Ek8DLYw@mail.gmail.com>
References: <CAKWHsQ=Es5jZ+sanz9DhWiiZFR34bTHSXmkXWaTCBxkCknAkrA@mail.gmail.com>
 <CAKWHsQkScEvbRGt8JpGm3j02QrfUZtRC0a0aNQnrFo2Ek8DLYw@mail.gmail.com>
Message-ID: <rcg70u$1qdb$1@ciao.gmane.io>

On 18/06/2020 14:36, Guro Anne Br?kken wrote:

> AttributeError                            Traceback (most recent call
> last)<ipython-input-9-801c1ba52996> in <module>----> 1
> st_spec.write('st_spec_data', format='SEGY')
> AttributeError: 'list' object has no attribute 'write'
> 
> The object type is "list", which does not make any sense since I will need
> floating point numbers.......

The list can hold anything but it's the list object that
needs to have a write() method. And it doesn't.

Looking again at your code:

st=obspy.read(\seismic\trace.segy)
st_spec=st.spectrogram(log=True, wlen=0.02,
                       samp_rate=32000, per_lap=0.9,
                       outfile="st_spec_image")

st_spec is the return value from st.spectrogram() and
it seems reasonable that spectrogram() would return a
list of values. Although I don't know what the outfile
parameter does in that case!

This is probably what you need to ask the obspy community.

-- 
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 maryknauth at mac.com  Fri Jun 19 10:44:17 2020
From: maryknauth at mac.com (Mary Knauth)
Date: Fri, 19 Jun 2020 10:44:17 -0400
Subject: [Tutor] Input parameters for functions
Message-ID: <C00F7B36-18DF-405F-A1F3-AB4991688D0D@mac.com>

Hello Everyone,

I have a script for a school assignment, an ATM transaction script based on the purpose of creating functions.
The draft I submitted all worked fine, but the feedback from my instructor was that I needed to use parameters in my functions.
Questions:
My original py script worked 100% with no parameters in the functions, so what is the advantage of adding the parameters?
I have put in what I think should be the parameters in my new py file, all the functions work, but do you think I have utilized the parameters correctly?
def balance(account_balance)
def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary?
def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary?

Many thanks in advance for your insight and thoughts.

Warm Regards,

Mary Knauth

954-412-9280
maryknauth at mac.com
http://www.zephyrsolutions.us <http://www.zephyrsolutions.us/>

 <https://zephyrsolutions.us/>  


From david at graniteweb.com  Fri Jun 19 19:04:28 2020
From: david at graniteweb.com (David Rock)
Date: Fri, 19 Jun 2020 18:04:28 -0500
Subject: [Tutor] Input parameters for functions
In-Reply-To: <C00F7B36-18DF-405F-A1F3-AB4991688D0D@mac.com>
References: <C00F7B36-18DF-405F-A1F3-AB4991688D0D@mac.com>
Message-ID: <20200619230428.GN7425@apple.graniteweb.com>

* Mary Knauth via Tutor <tutor at python.org> [2020-06-19 10:44]:
> Hello Everyone,
> 
> I have a script for a school assignment, an ATM transaction script
> based on the purpose of creating functions.  The draft I submitted all
> worked fine, but the feedback from my instructor was that I needed to
> use parameters in my functions.
>
> Questions:
> My original py script worked 100% with no parameters in the functions, so
> what is the advantage of adding the parameters?  I have put in what I think
> should be the parameters in my new py file, all the functions work, but do
> you think I have utilized the parameters correctly?
>
> Many thanks in advance for your insight and thoughts.

Hello, Mary. Welcome!

> My original py script worked 100% with no parameters in the functions, so
> what is the advantage of adding the parameters?  

The advantage of using parameters is it allows you to feed information
to the functions so it can be used with more than one static case.  For
example, your deposit function can be called with different values to
allow the same function to be used for any deposit amount, not just a
hard-coded amount.

> def balance(account_balance)
> def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary?
> def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary?

If you included your .py file, it probably got stripped.  The email list
does not normally accept any attachments.  Please send the text of the
file inside the body of the email if you want us to look at it.  That
said, account_balance is probably necessary in all cases because both
deposit and withdrawal functions have two pieces of information they
need to be successful: the account balance, and the dollar amount you
wish to add/subtract.

It looks to me like you are on the right track. :-)

-- 
David Rock
david at graniteweb.com

From david at graniteweb.com  Fri Jun 19 19:47:27 2020
From: david at graniteweb.com (David Rock)
Date: Fri, 19 Jun 2020 18:47:27 -0500
Subject: [Tutor] [maryknauth@mac.com: Re:  Input parameters for functions]
Message-ID: <20200619234727.GO7425@apple.graniteweb.com>

Mary,

I've forwarded your reply to the mailing list. Remember to reply to the list
email and not individuals so others can see the conversation (both to help and
to learn).  Comments inline below

> ----- Forwarded message from Mary Knauth <maryknauth at mac.com> -----
> 
> Hello David,
> 
> Thanks very much for the welcome, I?ve written a couple question so far to the
> python tutor group, and it?s amazing what knowledge you all give back, so thank
> you!
> 
> Here is my code:
> 
> import sys
> 
> # -------------------------- DECLARE variables for balance, deposit, and withdrawal --------------------------
> 
> account_balance = float(500.25)                                                 # Starting balance indicated by Codio
> deposit_amount = 0                                                              # Declare variable 'deposit_amount'
> withdrawal_amount = 0                                                           # Declare variable 'withdrawal_amount'
> 
> 
> # -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit -----------------------------
> 
> def balance(account_balance):                                                   # Define balance function
>   print("Your current balance: ", account_balance)                              # Prints the current avalible balance
> 
> def deposit(account_balance, deposit_amount):                                   # Define DEPOSIT function with parameters account_balance and deposit_amount
>   deposit_amount = float(input("How much would you like to deposit today?\n"))  # Accept user input for the deposit amount, in float format
>   balance = account_balance + deposit_amount                                    # This addition assigns the updated value of the account blance, to the variable 'BALANCE'
>   print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, balance))  # Prints depost amount and account balance
> 
> def withdrawal(account_balance, withdrawal_amount):                             # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount
>   withdrawal_amount = float(input("How much would you like to withdraw today?\n")) #  Accept user input for the withdrawal amount, in float format
>   if withdrawal_amount > account_balance:                                       # Checking to see if the amount requested, is greater than the amount avalible
>     print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds
>   else:                                                                         # Suffient amount of funds are avalible, the function continues
>     balance = account_balance - withdrawal_amount                               # Variable 'balance' is assigned to reflect the new avalible balance
>     print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, balance))  # Prints withdrawal amount and account balance


These are mostly fine for individual use-cases, but all they do is print
the temporary updated value.  For deposit and withdrawal, do you have a
requirement to remember the new values?  How would you update the global
variables with the new values from the functions to make them persistent? 


> # ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q -------------------------------------
> userChoice = 'go'                                                               # Setting the variable 'userChoice' to 'go', so we can impliment a while loop
> 
> while userChoice != 'E':                                                        # As long as the user does not select 'E' (Exit), the program will keep looping with user choices
> 
> # Step ONE =>  Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice'
>     userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper()
> 
> # Step TWO => conditional statement begins based on the value of variable 'userchoice' from user input
> # Four branches ustilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT
>     if (userChoice == 'D'):                                                     # Accepts input D and proceeds with function 'deposit'
>         deposit (account_balance, deposit_amount)                               # DEPOSIT function is called with parameters 'account_balance' and 'deposit_amount'
> 
>     elif (userChoice == 'B'):                                                   # Accepts input B and proceeds with function 'balance'
>         balance (account_balance)                                               # BALANCE function is called with parameter 'account_balance'
> 
>     elif (userChoice == 'W'):                                                   # Accepts input D and proceeds with function 'withdrawal'
>         withdrawal (account_balance, withdrawal_amount)                         # WITHDRAWAL function is called with parameters 'account_balance' and 'withdrawal_amount'
> 
>     elif (userChoice == 'E'):                                                   # Accepts input E for EXIT
>         print("Thank you for banking with us.")                                 # There is no function for EXIT, and therefore the user has a printed message ending their session


Overall, This is structured just fine.  The main thing I would look at
is what I mentioned above regarding value permanence.  To see what I
mean, run the program, but make several transactions in a row.  If you
subtract $100 and then check your balance, does it change?  If not, how
would you fix it?


-- 
David Rock
david at graniteweb.com

From alan.gauld at yahoo.co.uk  Fri Jun 19 19:49:20 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 20 Jun 2020 00:49:20 +0100
Subject: [Tutor] Input parameters for functions
In-Reply-To: <C00F7B36-18DF-405F-A1F3-AB4991688D0D@mac.com>
References: <C00F7B36-18DF-405F-A1F3-AB4991688D0D@mac.com>
Message-ID: <rcjiu1$1igm$1@ciao.gmane.io>

On 19/06/2020 15:44, Mary Knauth via Tutor wrote:

> My original py script worked 100% with no parameters in the functions, 
> so what is the advantage of adding the parameters?

To answer that we have to go back to basics and ask why write
functions in the first place?

There are basically two reasons_
a) The save us having to retype code every time we need it,
   we can just call the function.
b) We can reuse code in more than one program. Think about
   the standard library modules that you have probably used.
   eg. We can import sys and then use the functions (like exit)
   that are inside sys in every program.
c) They make our code easier to read by hiding the details
   of an operation. That doesn't really depend so  much
   on parameters, although it can help, but we will ignore
   it as an issue for now.

For case (a) it doesn't matter so much whether we use
parameters or not. It's our code, we know what it is doing.
We can use global variables and we know what those variables
are called. No problem.(Although if you need to use it on
different values within your program things change, as
you'll see below)

But in case (b) if we don't have parameters we must still
rely on global variables. And that means we must know the names
of those variables. But if the code that is calling our
function is in a different program how can we be sure it
has the same variable names? Or worse, that if it does use
the same names that it uses them the same way we did when
we wrote the function?

Consider a simple function that calculates the square
of a number:

def square()
   return x*x

Now that will work fine if we have a variable called x.

But if I try to import the code and use the square function
in another program I need to create a variable in my program
called x otherwise the function will fail. But the only
way I know to do that is if I read your code.
Easy in this case but imagine if the function had several
dozen (or hundred) lines of code inside! (Which is common
in professional size programs)

Now see what changes if we rewrite square using a parameter:

def square(x):
   return x*x

Now I can import your code and pass it any variable name
I like:

import mary_code

z = 42
print(mary_code.square(z))
y = 27
print(mary_code.square(y))


Notice I called square twice. The first time I passed
a variable called z, the second time I passed y.

Without the parameter I can't do that, I have to use
x so the equivalent code becomes:

import mary_code

z = 42
y = 22
x = z
print(mary_code.square())
x = y
print(mary_code.square())

Notice how I have to introduce an x value then copy the
values I want to use (z and y) into x before I can call
the function.

Now imagine I already have a variable called x that I'm
using for something else. Now it gets really messy. I have
to copy x to a temporary variable. Then copy my real
variable (z or y) to x. then call the function. Then
copy the temporary variable back into x.

And I have to do that every time I try to use the function.
Pretty soon the function is causing more work than it saves!

That's why its a good idea to make your functions like standalone
pieces of code with no dependencies on the external code
that calls them. Then you can use them across many projects,
or with many values in your own project.

> def balance(account_balance)
> def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary?
> def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary?

Yes that looks right. The deposit and withdrawal functions need to know
the starting balance and the amount. They can then return the ending
balance.

The first function may not be necessary if it just returns the value
given to it! But if it prints a nice message or checks it is not
negative or something then in that case it would be sensible to
tell it what the balance was. (Although we might rename it to
print_balance() or check_balance() perhaps)

Note: There are other problems associated with using global variables
in functions but they require much more complex examples and
only really apply to large programs so we can ignore them for now.

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 maryknauth at mac.com  Sat Jun 20 09:08:27 2020
From: maryknauth at mac.com (Mary Knauth)
Date: Sat, 20 Jun 2020 09:08:27 -0400
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <20200619234727.GO7425@apple.graniteweb.com>
References: <20200619234727.GO7425@apple.graniteweb.com>
Message-ID: <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>

David,

Thank you, I?ll remember to reply to the list from now on :)

You actually touched down on another question I had in my head, the value of accout_balance is temporary just as you stated.  I think I need to add return to my functions.

?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return.

Correct?

Warm Regards,

Mary Knauth
954-412-9280
maryknauth at mac.com



> On Jun 19, 2020, at 7:47 PM, David Rock <david at graniteweb.com> wrote:
> 
> ?Mary,
> 
> I've forwarded your reply to the mailing list. Remember to reply to the list
> email and not individuals so others can see the conversation (both to help and
> to learn).  Comments inline below
> 
>> ----- Forwarded message from Mary Knauth <maryknauth at mac.com> -----
>> 
>> Hello David,
>> 
>> Thanks very much for the welcome, I?ve written a couple question so far to the
>> python tutor group, and it?s amazing what knowledge you all give back, so thank
>> you!
>> 
>> Here is my code:
>> 
>> import sys
>> 
>> # -------------------------- DECLARE variables for balance, deposit, and withdrawal --------------------------
>> 
>> account_balance = float(500.25)                                                 # Starting balance indicated by Codio
>> deposit_amount = 0                                                              # Declare variable 'deposit_amount'
>> withdrawal_amount = 0                                                           # Declare variable 'withdrawal_amount'
>> 
>> 
>> # -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit -----------------------------
>> 
>> def balance(account_balance):                                                   # Define balance function
>>  print("Your current balance: ", account_balance)                              # Prints the current avalible balance
>> 
>> def deposit(account_balance, deposit_amount):                                   # Define DEPOSIT function with parameters account_balance and deposit_amount
>>  deposit_amount = float(input("How much would you like to deposit today?\n"))  # Accept user input for the deposit amount, in float format
>>  balance = account_balance + deposit_amount                                    # This addition assigns the updated value of the account blance, to the variable 'BALANCE'
>>  print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, balance))  # Prints depost amount and account balance
>> 
>> def withdrawal(account_balance, withdrawal_amount):                             # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount
>>  withdrawal_amount = float(input("How much would you like to withdraw today?\n")) #  Accept user input for the withdrawal amount, in float format
>>  if withdrawal_amount > account_balance:                                       # Checking to see if the amount requested, is greater than the amount avalible
>>    print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds
>>  else:                                                                         # Suffient amount of funds are avalible, the function continues
>>    balance = account_balance - withdrawal_amount                               # Variable 'balance' is assigned to reflect the new avalible balance
>>    print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, balance))  # Prints withdrawal amount and account balance
> 
> 
> These are mostly fine for individual use-cases, but all they do is print
> the temporary updated value.  For deposit and withdrawal, do you have a
> requirement to remember the new values?  How would you update the global
> variables with the new values from the functions to make them persistent? 
> 
> 
>> # ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q -------------------------------------
>> userChoice = 'go'                                                               # Setting the variable 'userChoice' to 'go', so we can impliment a while loop
>> 
>> while userChoice != 'E':                                                        # As long as the user does not select 'E' (Exit), the program will keep looping with user choices
>> 
>> # Step ONE =>  Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice'
>>    userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper()
>> 
>> # Step TWO => conditional statement begins based on the value of variable 'userchoice' from user input
>> # Four branches ustilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT
>>    if (userChoice == 'D'):                                                     # Accepts input D and proceeds with function 'deposit'
>>        deposit (account_balance, deposit_amount)                               # DEPOSIT function is called with parameters 'account_balance' and 'deposit_amount'
>> 
>>    elif (userChoice == 'B'):                                                   # Accepts input B and proceeds with function 'balance'
>>        balance (account_balance)                                               # BALANCE function is called with parameter 'account_balance'
>> 
>>    elif (userChoice == 'W'):                                                   # Accepts input D and proceeds with function 'withdrawal'
>>        withdrawal (account_balance, withdrawal_amount)                         # WITHDRAWAL function is called with parameters 'account_balance' and 'withdrawal_amount'
>> 
>>    elif (userChoice == 'E'):                                                   # Accepts input E for EXIT
>>        print("Thank you for banking with us.")                                 # There is no function for EXIT, and therefore the user has a printed message ending their session
> 
> 
> Overall, This is structured just fine.  The main thing I would look at
> is what I mentioned above regarding value permanence.  To see what I
> mean, run the program, but make several transactions in a row.  If you
> subtract $100 and then check your balance, does it change?  If not, how
> would you fix it?
> 
> 
> -- 
> David Rock
> david at graniteweb.com
> _______________________________________________
> 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 Jun 20 11:00:18 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 20 Jun 2020 16:00:18 +0100
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
Message-ID: <rcl8a2$1tcs$1@ciao.gmane.io>

On 20/06/2020 14:08, Mary Knauth via Tutor wrote:
>  I think I need to add return to my functions.

That's correct.

> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, 

Yes. You cannot combine assignment and another statement such as return.
(In the latest versions of Python there is a new feature that does allow
this but we will ignore that for now!)

You need to calculate the value first then return it.

account_balance = account_balance + deposit_amount
# possibly do more things with account_balance
return account_balance


If you don;t need to do anything with account_balance you can return the
calculation result directly:

return account_balance + deposit_amount

You may find the "Modules and Functions" topic of my tutorial helpful.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/l2p2
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 Jun 20 11:17:23 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 20 Jun 2020 09:17:23 -0600
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <rcl8a2$1tcs$1@ciao.gmane.io>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com> <rcl8a2$1tcs$1@ciao.gmane.io>
Message-ID: <272ed428-ac78-8288-8d59-9628108f977b@wichmann.us>

On 6/20/20 9:00 AM, Alan Gauld via Tutor wrote:
> On 20/06/2020 14:08, Mary Knauth via Tutor wrote:
>>  I think I need to add return to my functions.
> 
> That's correct.
> 
>> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, 
> 
> Yes. You cannot combine assignment and another statement such as return.
> (In the latest versions of Python there is a new feature that does allow
> this but we will ignore that for now!)
> 
> You need to calculate the value first then return it.
> 
> account_balance = account_balance + deposit_amount
> # possibly do more things with account_balance
> return account_balance
> 
> 
> If you don;t need to do anything with account_balance you can return the
> calculation result directly:
> 
> return account_balance + deposit_amount
> 
> You may find the "Modules and Functions" topic of my tutorial helpful.


I think you'll also find that this example will make more sense in a
context that will come up later in your learning: a way to have
persistent values that can be accessed by functions, without using
global variables, will be laid out when the course gets on to classes
and methods ("object oriented programming", although in Python it's all
objects actually). Have to lay the foundation first, though.





From alexkleider at protonmail.com  Sat Jun 20 11:23:31 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Sat, 20 Jun 2020 15:23:31 +0000
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
Message-ID: <bFAzHiufCMflt3Ksn8lUwiaRhljMPIGHlNdg-ALvLsRHtf2Vuca2ZENWRGKWAN-qbRsVNucXsAzdpOtN35OudH45zpq3reVX3m8Rtpucmtw=@protonmail.com>


??????? Original Message ???????
On Saturday, June 20, 2020 6:08 AM, Mary Knauth via Tutor <tutor at python.org> wrote:

>
> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return.

Try
    account_balance += deposit_amount
    return account_balance
or simply
    return account_balance + deposit_amount


From maryknauth at mac.com  Sat Jun 20 13:22:43 2020
From: maryknauth at mac.com (Mary Knauth)
Date: Sat, 20 Jun 2020 13:22:43 -0400
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <bFAzHiufCMflt3Ksn8lUwiaRhljMPIGHlNdg-ALvLsRHtf2Vuca2ZENWRGKWAN-qbRsVNucXsAzdpOtN35OudH45zpq3reVX3m8Rtpucmtw=@protonmail.com>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
 <bFAzHiufCMflt3Ksn8lUwiaRhljMPIGHlNdg-ALvLsRHtf2Vuca2ZENWRGKWAN-qbRsVNucXsAzdpOtN35OudH45zpq3reVX3m8Rtpucmtw=@protonmail.com>
Message-ID: <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com>

Thanks everyone for the good information!

I?ve updated the functions to reflect return account_balance, but when I run other transactions the balance still defaults to original $500.25

I realize this isn?t the best exercise, the course only wanted us to define the functions and then use them, it did not include a loop or return.  Just trying to figure out for my own curiosity.

def balance(account_balance):                                                   # Define balance function
  print("Your current balance is $%.2f" % (account_balance))                    # Prints the current avalible balance

def deposit(account_balance, deposit_amount):                                   # Define DEPOSIT function with parameters account_balance and deposit_amount
  deposit_amount = float(input("How much would you like to deposit today?\n"))  # Accept user input for the deposit amount, in float format
  account_balance += deposit_amount                                             # This addition assigns the updated value of the account blance, to the variable 'account_balance'
  print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, account_balance))  # Prints depost amount and account balance
  return account_balance                                                        # Return records the new value of account_balance to reflect accordingly in other transactions
  

def withdrawal(account_balance, withdrawal_amount):                             # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount
  withdrawal_amount = float(input("How much would you like to withdraw today?\n")) #  Accept user input for the withdrawal amount, in float format
  if withdrawal_amount > account_balance:                                       # Checking to see if the amount requested, is greater than the amount avalible
    print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds
  else:                                                                         # Suffient amount of funds are avalible, the function continues
    account_balance -= withdrawal_amount                                        # Variable 'account_balance' is assigned to reflect the new avalible balance
    print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, account_balance))  # Prints withdrawal amount and account balance
    return account_balance                                                      # Return records the new value of account_balance to reflect accordingly in other transactions


Warm Regards,

Mary Knauth

954-412-9280
maryknauth at mac.com
http://www.zephyrsolutions.us <http://www.zephyrsolutions.us/>

 <https://zephyrsolutions.us/>  

> On Jun 20, 2020, at 11:23, alexkleider <alexkleider at protonmail.com> wrote:
> 
> 
> ??????? Original Message ???????
> On Saturday, June 20, 2020 6:08 AM, Mary Knauth via Tutor <tutor at python.org> wrote:
> 
>> 
>> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return.
> 
> Try
>    account_balance += deposit_amount
>    return account_balance
> or simply
>    return account_balance + deposit_amount
> 


From alan.gauld at yahoo.co.uk  Sat Jun 20 13:57:14 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 20 Jun 2020 18:57:14 +0100
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
 <bFAzHiufCMflt3Ksn8lUwiaRhljMPIGHlNdg-ALvLsRHtf2Vuca2ZENWRGKWAN-qbRsVNucXsAzdpOtN35OudH45zpq3reVX3m8Rtpucmtw=@protonmail.com>
 <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com>
Message-ID: <rclilq$3l7$1@ciao.gmane.io>

On 20/06/2020 18:22, Mary Knauth via Tutor wrote:

> I?ve updated the functions to reflect return account_balance,> but when I run other transactions the balance still defaults to
original $500.25

I suspect that's because you are not assigning the returned value.
It is not enough to return the value you have to use it in your
calling code. Although your  parameter has the same name as the variable
in your main code that is purely coincidental. The parameter inside the
function has no impact on the variable outside. You need to assign the
function return value to the variable.

account_balance = 500.00
amount = float(input("How much to deposit?"))
account_balance = deposit(account_balance, amount)  # assign new balance
print(account_balance)                 # should now be 500+amount

> def deposit(account_balance, deposit_amount):
>   deposit_amount = float(input("How much would you like to deposit today?\n"))
>   account_balance += deposit_amount                                           
>   print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, account_balance))
>   return account_balance                                                       

Incidentally, it's considered best practice to avoid putting
calculations and input/output statements in the same function.
That's because it limits the ability to use the function in an
application that uses a different type of display - like a web app,
or GUI, say.


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



From david at graniteweb.com  Sat Jun 20 15:24:17 2020
From: david at graniteweb.com (David Rock)
Date: Sat, 20 Jun 2020 14:24:17 -0500
Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions]
In-Reply-To: <rclilq$3l7$1@ciao.gmane.io>
References: <20200619234727.GO7425@apple.graniteweb.com>
 <ED7CEEAA-A040-4476-ACC1-2AFE358BA5A6@mac.com>
 <bFAzHiufCMflt3Ksn8lUwiaRhljMPIGHlNdg-ALvLsRHtf2Vuca2ZENWRGKWAN-qbRsVNucXsAzdpOtN35OudH45zpq3reVX3m8Rtpucmtw=@protonmail.com>
 <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com>
 <rclilq$3l7$1@ciao.gmane.io>
Message-ID: <20200620192417.GS7425@apple.graniteweb.com>

* Alan Gauld via Tutor <tutor at python.org> [2020-06-20 18:57]:
> On 20/06/2020 18:22, Mary Knauth via Tutor wrote:
> 
> account_balance = 500.00
> amount = float(input("How much to deposit?"))
> account_balance = deposit(account_balance, amount)  # assign new balance
> print(account_balance)                 # should now be 500+amount

To stick with the functions you have already written, print(account_balance)
could (should?) be replaced by balance(account_balance)

As mentioned by others, the naming of that function is a little clunky.
Changing to print_balance() would be a little clearer what it actually
does (and explains why you would use it rather than just a simple print
statement).

-- 
David Rock
david at graniteweb.com

From robertvstepp at gmail.com  Sun Jun 21 15:34:25 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 21 Jun 2020 14:34:25 -0500
Subject: [Tutor] How to find all current instances of a class?
Message-ID: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>

I had (perhaps) naively hoped that classes had dunder methods to list
all current instances associated with that class, but if there is
something that simple I have yet to find it.  Does an easy, built-in
method exist to list all current instances of a particular class?

-- 
boB

From mats at wichmann.us  Sun Jun 21 15:46:39 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 21 Jun 2020 13:46:39 -0600
Subject: [Tutor] How to find all current instances of a class?
In-Reply-To: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
References: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
Message-ID: <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us>

On 6/21/20 1:34 PM, boB Stepp wrote:
> I had (perhaps) naively hoped that classes had dunder methods to list
> all current instances associated with that class, but if there is
> something that simple I have yet to find it.  Does an easy, built-in
> method exist to list all current instances of a particular class?

Python doesn't track this, so you gotta do it yourself.

Two thoughts:  (1) find all the objects - the garbage collector knows
this - and filter that. (2) have the class track it - you can make a
class attribute and add a weak reference to it each time the class
initializer is called. Or (3) some other way I didn't think of (pretty
much guaranteed to exist)

For the former, I *think* this will be good enough, it's off the top of
my head and so untested:

import gc

instances = [obj for obj in gc.get_objects() if isinstance(obj,
ClassWeWantToTrack)]

From alan.gauld at yahoo.co.uk  Sun Jun 21 17:42:28 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 21 Jun 2020 22:42:28 +0100
Subject: [Tutor] How to find all current instances of a class?
In-Reply-To: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
References: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
Message-ID: <rcok85$2aa4$1@ciao.gmane.io>

On 21/06/2020 20:34, boB Stepp wrote:
> I had (perhaps) naively hoped that classes had dunder methods to list
> all current instances associated with that class, but if there is
> something that simple I have yet to find it.  Does an easy, built-in
> method exist to list all current instances of a particular class?

Further to Mats' answer, I don't know any object system that does this,
not even Smalltalk or CLOS.(The two most complete OOP systems around)
After all there can be many millions of instances - think about
strings and integers.... Tracking each instance of those would be
a lot of work.

But the "normal" way to do it if you need that facility is to
create a classmethod/attribute that holds a list of instances.
(Possibly by overriding __new__ or __init__). In fact this is
often cited as an example of a class method(as opposed to an
instance method. This is often associated with classes whose
instances are persisted in a database. So you want to know if
a particular instance is "in memory" or still in storage.
You then access the instance appropriately.

But Mat's idea of using the garbage collector is a neat trick.
I'd never have thought of that one.

-- 
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  Sun Jun 21 19:21:30 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 21 Jun 2020 17:21:30 -0600
Subject: [Tutor] How to find all current instances of a class?
In-Reply-To: <rcok85$2aa4$1@ciao.gmane.io>
References: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
 <rcok85$2aa4$1@ciao.gmane.io>
Message-ID: <63817ee0-5a40-3a9f-c0f0-c01ba0ee0d73@wichmann.us>

On 6/21/20 3:42 PM, Alan Gauld via Tutor wrote:

> But Mat's idea of using the garbage collector is a neat trick.
> I'd never have thought of that one.

I read that idea somewhere once quite a while ago, not really taking
personal credit :)

From robertvstepp at gmail.com  Sun Jun 21 19:41:02 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 21 Jun 2020 18:41:02 -0500
Subject: [Tutor] How to find all current instances of a class?
In-Reply-To: <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us>
References: <CANDiX9L_JU0X5FrYpObe0XY0b721+a6J8pUvO00RTT-gwZSbag@mail.gmail.com>
 <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us>
Message-ID: <CANDiX9Lny=Z_Z8xGGZUaTD2FDc6iy6X9gwgLWVYHbiLLE+jsgg@mail.gmail.com>

On Sun, Jun 21, 2020 at 2:47 PM Mats Wichmann <mats at wichmann.us> wrote:
>
> On 6/21/20 1:34 PM, boB Stepp wrote:
> > I had (perhaps) naively hoped that classes had dunder methods to list
> > all current instances associated with that class, but if there is
> > something that simple I have yet to find it.  Does an easy, built-in
> > method exist to list all current instances of a particular class?
>
> Python doesn't track this, so you gotta do it yourself.

> For the former, I *think* this will be good enough, it's off the top of
> my head and so untested:
>
> import gc
>
> instances = [obj for obj in gc.get_objects() if isinstance(obj,
> ClassWeWantToTrack)]

Thanks, Mats, that does the trick quite nicely.  My interest in this
stems from exploring all the *hidden* information that is available
about classes and their instances.  After seeing all of the available
information it struck me that I had not seen anything tracking
instances.  But what you and Alan say makes sense -- may be many such
instances which would take unnecessary additional resources to track.

-- 
boB

From robertvstepp at gmail.com  Sun Jun 21 22:35:11 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 21 Jun 2020 21:35:11 -0500
Subject: [Tutor] Counting objects: method vs. staticmethod vs. classmethod
Message-ID: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>

What I want to do:  Every time I instantiate an object of a particular
class I wish to generate a unique id dependent on a particular
attribute value and the current number of objects created with that
attribute value.  Playing around tonight I have come up with the same
technique expressed slightly differently.  Which is best for what I
want to do?  Is there a better way to do what I want to do?

3.7.5:  import random
3.7.5:  from collections import Counter
3.7.5:  import string
3.7.5:  items = list(string.ascii_uppercase)
3.7.5:  def make_objs(n, items, cls):
...         for i in range(n):
...             obj = cls(random.choice(items))
...
3.7.5:  class A:
...         c = Counter()
...         def count(item):
...             A.c.update([item])
...         def __init__(self, item):
...             A.count(item)
...
3.7.5:  make_objs(1000, items, A)
3.7.5:  A.c
Counter({'U': 49, 'J': 47, 'Q': 47, 'A': 45, 'X': 45, 'Z': 44, 'S':
43, 'D': 42, 'T': 41, 'F': 41, 'O': 41, 'E': 40, 'Y': 38, 'W': 37,
'K': 37, 'H': 37, 'G': 37, 'N': 36, 'M': 35, 'B': 34, 'C': 33, 'R':
33, 'V': 32, 'I': 32, 'L': 29, 'P': 25})
3.7.5:  sum(A.c.values())
1000
3.7.5:  class B:
...         c = Counter()
...         @staticmethod
...         def count(item):
...             B.c.update([item])
...         def __init__(self, item):
...             B.count(item)
...
3.7.5:  make_objs(1000, items, B)
3.7.5:  B.c
Counter({'O': 52, 'X': 51, 'M': 50, 'G': 49, 'A': 49, 'P': 46, 'I':
45, 'H': 43, 'Z': 42, 'J': 42, 'L': 42, 'Q': 42, 'F': 41, 'D': 37,
'E': 37, 'N': 36, 'S': 33, 'C': 32, 'K': 32, 'R': 31, 'U': 31, 'W':
31, 'V': 30, 'T': 26, 'Y': 26, 'B': 24})
3.7.5:  class C:
...         c = Counter()
...         @classmethod
...         def count(cls, item):
...             C.c.update([item])
...         def __init__(self, item):
...             C.count(item)
...
3.7.5:  make_objs(1000, items, C)
3.7.5:  C.c
Counter({'R': 45, 'C': 45, 'Y': 44, 'A': 44, 'B': 44, 'K': 43, 'X':
43, 'E': 43, 'H': 42, 'P': 41, 'S': 41, 'Q': 41, 'L': 38, 'F': 38,
'I': 38, 'M': 37, 'U': 37, 'J': 37, 'O': 36, 'W': 35, 'G': 34, 'T':
34, 'V': 31, 'D': 31, 'Z': 30, 'N': 28})

The final counts are immaterial.  I would use the value of c at the
time of instantiation to generate its id attribute.  The id would be
used for __str__() to generate something like:  "R22 MyObjectName".

-- 
boB

From alan.gauld at yahoo.co.uk  Mon Jun 22 05:32:49 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 22 Jun 2020 10:32:49 +0100
Subject: [Tutor] Counting objects: method vs. staticmethod vs.
 classmethod
In-Reply-To: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>
References: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>
Message-ID: <rcpts1$33di$1@ciao.gmane.io>

On 22/06/2020 03:35, boB Stepp wrote:
> What I want to do:  Every time I instantiate an object of a particular
> class I wish to generate a unique id dependent on a particular
> attribute value and the current number of objects created with that
> attribute value.  Playing around tonight I have come up with the same
> technique expressed slightly differently.  Which is best for what I
> want to do?  Is there a better way to do what I want to do?

They all can work, its mostly down to semantics.

global functions are notionally for working with objects of any
type.

class methods are for working with the instances of a particular
class,

static methods are, IMHO, a fudge that I never use!

So semantically, if you want to apply the function to multiple
classes - or all then make it a global function. (In fact you may
really want to look into tinkering with the metaclass mechanism!!)
You might also consider adding a call to the fuction from the __init__()
methods of the relevant classes.

But if its a single class, or a class hierarchy, then make it
a class method. (If its a few unrelated classes you could also
make it a class method of a mixin class which you then inherit
into all of the target classes.)

In practice it won't make much difference but in terms
of expressing intent it is probably bet to locate it where
the purpose suggests.

-- 
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  Mon Jun 22 10:46:21 2020
From: __peter__ at web.de (Peter Otten)
Date: Mon, 22 Jun 2020 16:46:21 +0200
Subject: [Tutor] Counting objects: method vs. staticmethod vs.
 classmethod
References: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>
Message-ID: <rcqg80$1ogu$1@ciao.gmane.io>

boB Stepp wrote:

> What I want to do:  Every time I instantiate an object of a particular
> class I wish to generate a unique id dependent on a particular
> attribute value and the current number of objects created with that
> attribute value.  Playing around tonight I have come up with the same
> technique expressed slightly differently.  Which is best for what I
> want to do?  Is there a better way to do what I want to do?
> 
> 3.7.5:  import random
> 3.7.5:  from collections import Counter
> 3.7.5:  import string
> 3.7.5:  items = list(string.ascii_uppercase)
> 3.7.5:  def make_objs(n, items, cls):
> ...         for i in range(n):
> ...             obj = cls(random.choice(items))
> ...
> 3.7.5:  class A:
> ...         c = Counter()
> ...         def count(item):
> ...             A.c.update([item])
> ...         def __init__(self, item):
> ...             A.count(item)
> ...
> 3.7.5:  make_objs(1000, items, A)
> 3.7.5:  A.c
> Counter({'U': 49, 'J': 47, 'Q': 47, 'A': 45, 'X': 45, 'Z': 44, 'S':
> 43, 'D': 42, 'T': 41, 'F': 41, 'O': 41, 'E': 40, 'Y': 38, 'W': 37,
> 'K': 37, 'H': 37, 'G': 37, 'N': 36, 'M': 35, 'B': 34, 'C': 33, 'R':
> 33, 'V': 32, 'I': 32, 'L': 29, 'P': 25})
> 3.7.5:  sum(A.c.values())
> 1000
> 3.7.5:  class B:
> ...         c = Counter()
> ...         @staticmethod
> ...         def count(item):
> ...             B.c.update([item])
> ...         def __init__(self, item):
> ...             B.count(item)
> ...
> 3.7.5:  make_objs(1000, items, B)
> 3.7.5:  B.c
> Counter({'O': 52, 'X': 51, 'M': 50, 'G': 49, 'A': 49, 'P': 46, 'I':
> 45, 'H': 43, 'Z': 42, 'J': 42, 'L': 42, 'Q': 42, 'F': 41, 'D': 37,
> 'E': 37, 'N': 36, 'S': 33, 'C': 32, 'K': 32, 'R': 31, 'U': 31, 'W':
> 31, 'V': 30, 'T': 26, 'Y': 26, 'B': 24})
> 3.7.5:  class C:
> ...         c = Counter()
> ...         @classmethod
> ...         def count(cls, item):
> ...             C.c.update([item])
> ...         def __init__(self, item):
> ...             C.count(item)
> ...
> 3.7.5:  make_objs(1000, items, C)
> 3.7.5:  C.c
> Counter({'R': 45, 'C': 45, 'Y': 44, 'A': 44, 'B': 44, 'K': 43, 'X':
> 43, 'E': 43, 'H': 42, 'P': 41, 'S': 41, 'Q': 41, 'L': 38, 'F': 38,
> 'I': 38, 'M': 37, 'U': 37, 'J': 37, 'O': 36, 'W': 35, 'G': 34, 'T':
> 34, 'V': 31, 'D': 31, 'Z': 30, 'N': 28})
> 
> The final counts are immaterial.  I would use the value of c at the
> time of instantiation to generate its id attribute.  The id would be
> used for __str__() to generate something like:  "R22 MyObjectName".

If you want to associate behaviour with a class that does not depend on the 
instance use static methods; if you want/expect that behaviour to change in 
subclasses use a class method.

> ...         @classmethod
> ...         def count(cls, item):
> ...             C.c.update([item])

That implementation defeats the purpose of class methods.

>From within the class method access the class via the first argument:

    @classmethod
    def count(cls, item):
        cls.c.update([item])

That way you can tweak the code in subclassses. Likewise the initializer

> ...         def __init__(self, item):
> ...             C.count(item)

becomes

    def __init__(self, item):
        self.count(item)

A complete example based on the code you posted:

$ cat classmethod_demo.py       
import random
import string

from collections import Counter


class C:
    c = Counter()

    @classmethod
    def count(cls, item):
        cls.c.update([item])

    def __init__(self, item):
        self.count(item)

class D(C):
    c = Counter()

classes = C, D

for i in range(10):
    code = random.choice(string.ascii_uppercase)
    cls = random.choice(classes)
    obj = cls(code)

for cls in classes:
    print("Created {} instances of {}:".format(
        sum(cls.c.values()), cls.__name__
    ))
    print(cls.c)
    print()

$ python3 classmethod_demo.py
Created 4 instances of C:
Counter({'M': 2, 'K': 1, 'Z': 1})

Created 6 instances of D:
Counter({'J': 2, 'H': 1, 'D': 1, 'N': 1, 'I': 1})




From mats at wichmann.us  Mon Jun 22 15:09:28 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 22 Jun 2020 13:09:28 -0600
Subject: [Tutor] Counting objects: method vs. staticmethod vs.
 classmethod
In-Reply-To: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>
References: <CANDiX9+gBq4LG2WmYmtLRdZEkADGYgFqdkKXB4-2FHs=o-UYLA@mail.gmail.com>
Message-ID: <cb0b91fd-adf3-4774-b813-07e431c19791@wichmann.us>

On 6/21/20 8:35 PM, boB Stepp wrote:
> What I want to do:  Every time I instantiate an object of a particular
> class I wish to generate a unique id dependent on a particular
> attribute value and the current number of objects created with that
> attribute value.  Playing around tonight I have come up with the same
> technique expressed slightly differently.  Which is best for what I
> want to do?  Is there a better way to do what I want to do?
> 
> 3.7.5:  import random
> 3.7.5:  from collections import Counter

by the way - bravo for using this "advanced" feature!  :)



From robertvstepp at gmail.com  Tue Jun 23 08:58:36 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 23 Jun 2020 07:58:36 -0500
Subject: [Tutor] Testing classes with class variables: How best to reset
 class state between tests?
Message-ID: <CANDiX9KFTO6aqDqnO=UrC0AXrD4kPT_m8MOhUf4U-EJ-VbP50w@mail.gmail.com>

class MyClass:
    class_var1 = value1
    class_var2 = value2
    ...

    methods some which may affect class variables

This is a spinoff of my earlier questions about creating an instance
counter for a class.  I started to implement this in my actual code
and started to write tests for the counter.  I quickly realized that
the counter variable retained state between tests, and, in fact,
already written tests would now populate the counter before I ever got
around to the new counter tests.  So how to best deal with this?  Two
ideas come immediately to mind:

1) Use setup and/or teardown methods to manually reset all class
variables to their desired initial state.  A downside of this is that
I will have to go back to all previous tests involving this class and
add these methods.

2) Forcibly reloading the import with importlib.reload(myclassmodule).
This seems like using a sledge hammer to swat a fly.  And it would
seem that it would have to be done repeatedly and added to earlier
tests as well.

Does Python provide a better solution?  For the record my test runner
is currently pytest.

TIA!

-- 
boB

From __peter__ at web.de  Wed Jun 24 02:53:45 2020
From: __peter__ at web.de (Peter Otten)
Date: Wed, 24 Jun 2020 08:53:45 +0200
Subject: [Tutor] Testing classes with class variables: How best to reset
 class state between tests?
References: <CANDiX9KFTO6aqDqnO=UrC0AXrD4kPT_m8MOhUf4U-EJ-VbP50w@mail.gmail.com>
Message-ID: <rcut9q$1gie$1@ciao.gmane.io>

boB Stepp wrote:

> class MyClass:
>     class_var1 = value1
>     class_var2 = value2
>     ...
> 
>     methods some which may affect class variables
> 
> This is a spinoff of my earlier questions about creating an instance
> counter for a class.  I started to implement this in my actual code
> and started to write tests for the counter.  I quickly realized that
> the counter variable retained state between tests, and, in fact,
> already written tests would now populate the counter before I ever got
> around to the new counter tests.  So how to best deal with this?  Two
> ideas come immediately to mind:
> 
> 1) Use setup and/or teardown methods to manually reset all class
> variables to their desired initial state.  A downside of this is that
> I will have to go back to all previous tests involving this class and
> add these methods.

setUp()/tearDown() seems fine. Put them into a base class that you can 
derive from to avoid repetition.

> 
> 2) Forcibly reloading the import with importlib.reload(myclassmodule).
> This seems like using a sledge hammer to swat a fly.  And it would
> seem that it would have to be done repeatedly and added to earlier
> tests as well.

That's a hack; you can never be sure that you have replaced all objects from 
the previous import.
 
> Does Python provide a better solution?  For the record my test runner
> is currently pytest.

While I think (1) is fine you may also consider pytest's autouse fixtures.



From samuelearabia10 at gmail.com  Wed Jun 24 16:45:04 2020
From: samuelearabia10 at gmail.com (Samuele)
Date: Wed, 24 Jun 2020 22:45:04 +0200
Subject: [Tutor] I Have An Error OS: Windows 10 Python: 3.7 thanks for the
 help
Message-ID: <CAEJnzLZEYXmb-C6-r2qYsq+43R17WkHRdvXMPbE7rYD-eL0v6g@mail.gmail.com>

i start to learn kivy i do the first start but i have an error
i have 2 files the code is below :

the Kivy code is :

<MainWindow>:
    BoxLayout:
            id: main_box
            orientation: "vertical"


the Python code is :

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class MainWindow(BoxLayout):
    pass


class MainApp(App):
    def build(self):
        return MainWindow()


sample_app = MainApp()
sample_app.run()





this is the error :
[INFO   ] [Logger      ] Record log in
C:\Users\marti\.kivy\logs\kivy_20-06-24_26.txt
[INFO   ] [Kivy        ] v1.11.1
[INFO   ] [Kivy        ] Installed at
"C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\__init__.py"
[INFO   ] [Python      ] v3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51)
[MSC v.1914 64 bit (AMD64)]
[INFO   ] [Python      ] Interpreter at
"C:\Users\marti\PycharmProjects\Project [Atom]\venv\Scripts\python.exe"
[INFO   ] [Factory     ] 184 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_gif (img_sdl2,
img_pil, img_ffpyplayer ignored)
 Traceback (most recent call last):
   File "C:/Users/marti/PycharmProjects/Test Kivy/main.py", line 15, in
<module>
     sample_app.run()
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\app.py", line 828, in run
     self.load_kv(filename=self.kv_file)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\app.py", line 599, in load_kv
     root = Builder.load_file(rfilename)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file
     return self.load_string(data, **kwargs)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 368, in
load_string
     parser = Parser(content=string, filename=fn)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 401, in __init__
     self.parse(content)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 510, in parse
     objects, remaining_lines = self.parse_level(0, lines)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 614, in parse_level
     level + 1, lines[i:], spaces)
   File "C:\Users\marti\PycharmProjects\Project
[Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 673, in parse_level
     if current_property[:3] == 'on_':
 TypeError: 'NoneType' object is not subscriptable

Process finished with exit code 1

From alan.gauld at yahoo.co.uk  Wed Jun 24 16:56:50 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 24 Jun 2020 21:56:50 +0100
Subject: [Tutor] I Have An Error OS: Windows 10 Python: 3.7 thanks for
 the help
In-Reply-To: <CAEJnzLZEYXmb-C6-r2qYsq+43R17WkHRdvXMPbE7rYD-eL0v6g@mail.gmail.com>
References: <CAEJnzLZEYXmb-C6-r2qYsq+43R17WkHRdvXMPbE7rYD-eL0v6g@mail.gmail.com>
Message-ID: <rd0emi$3s84$1@ciao.gmane.io>

On 24/06/2020 21:45, Samuele wrote:
> i start to learn kivy i do the first start but i have an error
> i have 2 files the code is below :

Since there is almost no Python there it is hard to see what
the error might be unless you know kivy.

This is really a kivy issue and you will probably get a
better response asking on the kivy forum.

https://kivy.org/#forum

HTH,

Alan G.

> 
> the Kivy code is :
> 
> <MainWindow>:
>     BoxLayout:
>             id: main_box
>             orientation: "vertical"
> 
> 
> the Python code is :
> 
> from kivy.app import App
> from kivy.uix.boxlayout import BoxLayout
> 
> 
> class MainWindow(BoxLayout):
>     pass
> 
> 
> class MainApp(App):
>     def build(self):
>         return MainWindow()
> 
> 
> sample_app = MainApp()
> sample_app.run()
> 
> 
> 
> 
> 
> this is the error :
> [INFO   ] [Logger      ] Record log in
> C:\Users\marti\.kivy\logs\kivy_20-06-24_26.txt
> [INFO   ] [Kivy        ] v1.11.1
> [INFO   ] [Kivy        ] Installed at
> "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\__init__.py"
> [INFO   ] [Python      ] v3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51)
> [MSC v.1914 64 bit (AMD64)]
> [INFO   ] [Python      ] Interpreter at
> "C:\Users\marti\PycharmProjects\Project [Atom]\venv\Scripts\python.exe"
> [INFO   ] [Factory     ] 184 symbols loaded
> [INFO   ] [Image       ] Providers: img_tex, img_dds, img_gif (img_sdl2,
> img_pil, img_ffpyplayer ignored)
>  Traceback (most recent call last):
>    File "C:/Users/marti/PycharmProjects/Test Kivy/main.py", line 15, in
> <module>
>      sample_app.run()
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\app.py", line 828, in run
>      self.load_kv(filename=self.kv_file)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\app.py", line 599, in load_kv
>      root = Builder.load_file(rfilename)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file
>      return self.load_string(data, **kwargs)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 368, in
> load_string
>      parser = Parser(content=string, filename=fn)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 401, in __init__
>      self.parse(content)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 510, in parse
>      objects, remaining_lines = self.parse_level(0, lines)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 614, in parse_level
>      level + 1, lines[i:], spaces)
>    File "C:\Users\marti\PycharmProjects\Project
> [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 673, in parse_level
>      if current_property[:3] == 'on_':
>  TypeError: 'NoneType' object is not subscriptable
> 
> Process finished with exit code 1
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 


-- 
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 savageapple850 at gmail.com  Thu Jun 25 10:56:12 2020
From: savageapple850 at gmail.com (Cravan)
Date: Thu, 25 Jun 2020 22:56:12 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
Message-ID: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>

Hi all,

??????????????? I recently embarked on learning Q-learning in python, but got an error that I?ve no idea how to fix. So here?s my code in one of my .py files: 

 

```

class Zomb(pg.sprite.Sprite):

??? def __init__(self, game, m, n):

??????? self.groups = game.all_sprites, game.zombs

??????? pg.sprite.Sprite.__init__(self, self.groups)

??????? self.game = game

??????? self.image = game.zomb_img

??????? self.rect = self.image.get_rect()

??????? self.pos = vec(m, n) * TILESIZE

??????? self.m = m

??????? self.n = n

??????? #self.pos.x will return the x-coordinate in the grid world

??????? self.stateSpace = [i for i in range(int(GRIDWIDTH) * int(GRIDHEIGHT))]

??????? self.actionSpace = {'U': vec(0, -self.m), 'D': vec(0, self.m),

??????????????????????????? 'L': vec(-1,0), 'R': vec(1,0)}

??????? self.possibleActions = ['U', 'D', 'L', 'R']

??????? self.vel = vec(0, 0)

??????? self.acc = vec(0, 0)

??????? self.rect.center = self.pos

??????? self.rotate = 0

 

 ???def setState(self, state):

??????? self.pos = state

 

??? def TerminalState(self, state):

??????? if self.game.health == 0:

??????????? return True

??????? else:

??????????? return False

 

??? def step(self, action):

??????? x, y = self.pos.x, self.pos.y

??????? resultingState = self.pos + self.actionSpace[action]

??????? self.game.reward = -1 if not self.TerminalState(resultingState) else 0

??????? self.setState(resultingState)

??????? return resultingState,self.game.reward,\

??????????? self.TerminalState(resultingState), None

 

??? def actionSpaceSample(self):

??????? return np.random.choice(self.possibleActions)

 

??? def update(self):

??????? self.image = game.zomb_img

??????? self.rect = self.image.get_rect()

????? ??self.rect.center = self.pos

??????? self.acc = vec(ZOMB_SPEED, 0)

??????? self.acc += self.vel * -1

??????? self.vel += self.acc * self.game.dt

??????? self.pos += self.vel * self.game.dt + 0.5 * self.acc * self.game.dt ** 2

??????? print(self.pos)

```

And here?s the processing part in my main .py file:

`````

g = Game()

def maxAction(Q, state, actions):

??? values = np.array([Q[state,a] for a in actions])

??? action = np.argmax(values)

??? return actions[action]

while True:

??? g.new()

 

??? ALPHA = 0.1

??? GAMMA = 1.0

??? EPS = 1.0

??? Q = {}

??? for zomb in g.zombs:

??????? for state in zomb.stateSpace:

??????????? for action in zomb.possibleActions:

??????????????? Q[state, action] = 0

??? numGames = 10

??? totalRewards = np.zeros(numGames)

??? for i in range(numGames):

??????? print('starting game ', i)

??????? done = False

??????? g.new()

??????? epRewards = 0

 

??? while not done:

??????? rand = np.random.random()

??????? for zomb in g.zombs:

??????????? observation = zomb.pos

??????????? action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \

??????????????????????????????????????????????????????? else zomb.actionSpaceSample()

 

??????????? observationnew, reward, done, info = zomb.step(action)

??????? epRewards += reward

 

??????? for zomb in g.zombs:

??????????? possible_actions = zomb.possibleActions

??????????? action = maxAction(Q, observationnew, possible_actions)

 

??????? Q[observation,action] = Q[observation,action] + ALPHA*(reward + \

??????????????????? GAMMA*Q[observationnew,action_] - Q[observation,action])

??????? observation = observationnew

??????? if EPS - 2 / numGames > 0:

??????????? EPS -= 2 / numGames

??????? else:

??????????? EPS = 0

??????? totalRewards[i] = epRewards

 

g.run()

````

 

However when I run the second file I encounter an error:

Traceback (most recent call last):

? File "maze.py", line 170, in <module>

??? action = maxAction(Q, observationnew, possible_actions)

? File "maze.py", line 136, in maxAction

??? values = np.array([Q[state,a] for a in actions])

? File "maze.py", line 136, in <listcomp>

??? values = np.array([Q[state,a] for a in actions])

TypeError: unhashable type: 'pygame.math.Vector2'


From savageapple850 at gmail.com  Thu Jun 25 11:05:30 2020
From: savageapple850 at gmail.com (Cravan)
Date: Thu, 25 Jun 2020 23:05:30 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
Message-ID: <B836AD84-5A12-414F-B270-633FF29E0D6B@gmail.com>

Hi all,

??????????????? I recently began learning Q-learning in Python but encountered an error. Here?s my code for the Agent in one of my .py files:

````

class Zomb(pg.sprite.Sprite):

??? def __init__(self, game, m, n):

??????? self.groups = game.all_sprites, game.zombs

??????? pg.sprite.Sprite.__init__(self, self.groups)

??????? self.game = game

??????? self.image = game.zomb_img

??????? self.rect = self.image.get_rect()

??????? self.pos = vec(m, n) * TILESIZE

??????? self.m = m

??????? self.n = n

??????? #self.pos.x will return the x-coordinate in the grid world

??????? self.stateSpace = [i for i in range(int(GRIDWIDTH) * int(GRIDHEIGHT))]

??????? self.actionSpace = {'U': vec(0, -self.m), 'D': vec(0, self.m),

??????????????????????????? 'L': vec(-1,0), 'R': vec(1,0)}

??????? self.possibleActions = ['U', 'D', 'L', 'R']

??????? self.vel = vec(0, 0)

??????? self.acc = vec(0, 0)

??????? self.rect.center = self.pos

??????? self.rotate = 0

 

??? def setState(self, state):

??????? self.pos = state

 

??? def TerminalState(self, state):

??????? if self.game.health == 0:

??????????? return True

??????? else:

??????????? return False

 

??? def step(self, action):

??????? x, y = self.pos.x, self.pos.y

??????? resultingState = self.pos + self.actionSpace[action]

??????? self.game.reward = -1 if not self.TerminalState(resultingState) else 0

??????? self.setState(resultingState)

??????? return resultingState,self.game.reward,\

??????????? self.TerminalState(resultingState), None

 

??? def actionSpaceSample(self):

??????? return np.random.choice(self.possibleActions)

 

??? def update(self):

??????? self.image = game.zomb_img

??????? self.rect = self.image.get_rect()

??????? self.rect.center = self.pos

??????? self.acc = vec(ZOMB_SPEED, 0)

??????? self.acc += self.vel * -1

??????? self.vel += self.acc * self.game.dt

??????? self.pos += self.vel * self.game.dt + 0.5 * self.acc * self.game.dt ** 2

??????? print(self.pos)

````

And here?s the processing and implementation of Q-learning in my main code:

````

g = Game()

def maxAction(Q, state, actions):

??? values = np.array([Q[state,a] for a in actions])

??? action = np.argmax(values)

??? return actions[action]

while True:

??? g.new()

 

??? ALPHA = 0.1

??? GAMMA = 1.0

??? EPS = 1.0

??? Q = {}

??? for zomb in g.zombs:

??????? for state in zomb.stateSpace:

??????????? for action in zomb.possibleActions:

??????????????? Q[state, action] = 0

??? numGames = 10

??? totalRewards = np.zeros(numGames)

??? for i in range(numGames):

??????? print('starting game ', i)

??????? done = False

??????? g.new()

??????? epRewards = 0

 

??? while not done:

??????? rand = np.random.random()

??????? for zomb in g.zombs:

??????????? observation = zomb.pos

??????????? action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \

 ???????????????????????????????????????????????????????else zomb.actionSpaceSample()

 

??????????? observationnew, reward, done, info = zomb.step(action)

??????? epRewards += reward

 

??????? for zomb in g.zombs:

??????????? possible_actions = zomb.possibleActions

??????????? action = maxAction(Q, observationnew, possible_actions)

 

??????? Q[observation,action] = Q[observation,action] + ALPHA*(reward + \

??????????????????? GAMMA*Q[observationnew,action_] - Q[observation,action])

??????? observation = observationnew

??????? if EPS - 2 / numGames > 0:

??????????? EPS -= 2 / numGames

??????? else:

??????????? EPS = 0

??????? totalRewards[i] = epRewards

 

g.run()

````

However, this error popped out:

######

Traceback (most recent call last):

? File "maze.py", line 170, in <module>

??? action = maxAction(Q, observationnew, possible_actions)

? File "maze.py", line 136, in maxAction

??? values = np.array([Q[state,a] for a in actions])

? File "maze.py", line 136, in <listcomp>

??? values = np.array([Q[state,a] for a in actions])

TypeError: unhashable type: 'pygame.math.Vector2'

######

Could someone provide me with a way to rectify this problem? (removing the vector sign in the dictionary doesn?t seem to help, another error pops up). 

Thanks,

Cravan

 

P.S. Also erm I made a buncha mistakes along the way, would appreciate any suggestion or help. Thanks!


From mats at wichmann.us  Thu Jun 25 11:20:42 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 25 Jun 2020 09:20:42 -0600
Subject: [Tutor] Testing classes with class variables: How best to reset
 class state between tests?
In-Reply-To: <rcut9q$1gie$1@ciao.gmane.io>
References: <CANDiX9KFTO6aqDqnO=UrC0AXrD4kPT_m8MOhUf4U-EJ-VbP50w@mail.gmail.com>
 <rcut9q$1gie$1@ciao.gmane.io>
Message-ID: <bdb3ce4a-9611-7f8e-1319-9716ee7d5069@wichmann.us>

On 6/24/20 12:53 AM, Peter Otten wrote:
> boB Stepp wrote:
> 
>> class MyClass:
>>     class_var1 = value1
>>     class_var2 = value2
>>     ...
>>
>>     methods some which may affect class variables
>>
>> This is a spinoff of my earlier questions about creating an instance
>> counter for a class.  I started to implement this in my actual code
>> and started to write tests for the counter.  I quickly realized that
>> the counter variable retained state between tests, and, in fact,
>> already written tests would now populate the counter before I ever got
>> around to the new counter tests.  So how to best deal with this?  Two
>> ideas come immediately to mind:
>>
>> 1) Use setup and/or teardown methods to manually reset all class
>> variables to their desired initial state.  A downside of this is that
>> I will have to go back to all previous tests involving this class and
>> add these methods.
> 
> setUp()/tearDown() seems fine. Put them into a base class that you can 
> derive from to avoid repetition.

the concept of setup and teardown in testing is pretty fundamental,
without it tests which affect state will cause your overall test run to
be a mess, so you shouldn't be uncomfortable with it.

autouse seems to be pytest's way to go a bit beyond the "classic {x}Unit
way" and make things a bit more usable.  I had to look it up, was new to
me :)  See, we all learn something from these interactions!

This example seems to fit your case fairly well:

https://docs.pytest.org/en/stable/fixture.html#autouse-fixtures

From mats at wichmann.us  Thu Jun 25 12:06:04 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 25 Jun 2020 10:06:04 -0600
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
Message-ID: <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>

On 6/25/20 8:56 AM, Cravan wrote:
> Hi all,
> 
> ??????????????? I recently embarked on learning Q-learning in python, but got an error that I?ve no idea how to fix. So here?s my code in one of my .py files: 

> However when I run the second file I encounter an error:
> 
> Traceback (most recent call last):
> ? File "maze.py", line 170, in <module>
> ??? action = maxAction(Q, observationnew, possible_actions)
> ? File "maze.py", line 136, in maxAction
> ??? values = np.array([Q[state,a] for a in actions])
> ? File "maze.py", line 136, in <listcomp>
> ??? values = np.array([Q[state,a] for a in actions])
> TypeError: unhashable type: 'pygame.math.Vector2'

a TypeError generically means you are using an incompatible data type in
place which has a restriction on what types can be used.

Your Q is a dictionary;

    Q = {}

and dicts specifically have the restriction that the type be hashable
(meaning it must be a type that doesn't change during runtime, like a
list - or a 2d Vector in your case), because when a key is inserted into
the dict, Python stores the hash of it for later lookups, and if, later,
it would hash differently because it has changed, the lookup wouldn't work.

the "state" you pass to maxAction, where the error was raised, looks
like it's probably a vector since it sounds like it represents a position:

            observation = zomb.pos
            action = maxAction(Q, observation, zomb.possibleActions) if
rand < (1-EPS) \
                                                        else
zomb.actionSpaceSample()

if zomb.pos was indeed a Vector2, then indexing Q using that as part of
the (state, a) tuple is the cause of your problem. Are you sure it's a
position you wanted to pass in this call?

     values = np.array([Q[state,a] for a in actions])


From mats at wichmann.us  Thu Jun 25 12:17:52 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 25 Jun 2020 10:17:52 -0600
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
Message-ID: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>

On 6/25/20 10:06 AM, Mats Wichmann wrote:

sigh... think one thing, write another:

> Your Q is a dictionary;
> 
>     Q = {}
> 
> and dicts specifically have the restriction that the type be hashable

... that the _key_ be hashable ...

From savageapple850 at gmail.com  Thu Jun 25 19:40:00 2020
From: savageapple850 at gmail.com (Cravan)
Date: Fri, 26 Jun 2020 07:40:00 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
Message-ID: <72714CDD-59CB-4F90-85A7-15EDA3F13449@gmail.com>

Hmm, I think I'll reconsider the use of vectors altogether. Thanks Mats! Appreciate your quick response!
Cheers,
Cravan



>    On 6/25/20 10:06 AM, Mats Wichmann wrote:
    
>  sigh... think one thing, write another:
    
    > Your Q is a dictionary;
    > 
    >     Q = {}
    > 
    > and dicts specifically have the restriction that the type be hashable
    
    ... that the _key_ be hashable ...
    _______________________________________________
    Tutor maillist  -  Tutor at python.org
    To unsubscribe or change subscription options:
    https://mail.python.org/mailman/listinfo/tutor
    



From PyTutor at DancesWithMice.info  Thu Jun 25 21:50:26 2020
From: PyTutor at DancesWithMice.info (DL Neil)
Date: Fri, 26 Jun 2020 13:50:26 +1200
Subject: [Tutor] Review: Good Habits for Great Coding
Message-ID: <b45962b9-32f9-a794-e2d5-66e59b64441e@etelligence.info>

Good Habits for Great Coding : Improving Programming Skills with 
Examples in Python,
Michael Stueben,
Apress, 2018


My disappointment with this book is largely a consequence of my own 
expectations. The title raised hopes that it would improve my own coding 
efforts, or that it would offer teaching techniques which might improve 
my approach to training in IT.

The first indication of a poor 'fit' was its dedication "to the isolated 
CS teacher and student". Sadly, many of the errors or examples of poor 
teaching would not have occurred, had the author been less 'isolated' 
and spent time interacting with the world-wide Python community!

The Introduction reveals the author to be a victim of his environment. 
School math and 'toy examples' lead to the conclusion that 
short/algebra-like variable-identification is "efficient" and that 
'pretty boxes' around module docstrings add value and improve 'looks'. 
Yet, the later chapter on "Self-Documenting Code" reverses such advice, 
instead preferring descriptively-meaningful names.

Whilst it is not necessary for all code to adhere to PEP-8 standards, it 
is difficult to imagine why one would deliberately teach differently, eg 
re-defining indentation. Generally, C- and Java-esque techniques do not 
transfer to Python. For example, camel-case for variable or function 
names is frowned-upon, but such, and the likes of for...in range(...) 
constructs, appear with alarming frequency. In eschewing the generic 
'in-joke' function names such as "foo", "bar", and "baz" (which few 
would ever use in practice anyway), the author instead promotes the 
no-less meaningful "doIt()" for general-purposes, purportedly following 
a verb-object name-form recommendation.

Similarly, but contrary to the usual EAFP/'we're all adults' ethos of 
the Python world; in the book's programmer-as-user example exercises 
there is emphasis on "testing for any pre-condition and boundary 
condition". In that environment, using assert to 'prove' an input or a 
result might be acceptable, but in 'the real world' risking such a 
hard-stop (decorated by a user-alarming error message and trace-back) 
would not. Conversely, in the "Expert Advice" chapter we read that 
"Robust code...heals itself...crashes gracefully".

A single, solitary use of the pythonic try...except structure can be 
recalled, but those keywords do not appear in the book's index. The 
'batteries included' advantages of the Python Standard Library don't 
receive coverage. Indeed the author details 'utility code' to 
debug-print a matrix structure, whereas most of us would reach for the 
pprint library. Ironically, recalling the development of such code, 
gives occasion to introduce the concept of "YAGNI".

Stueben concludes (rightly) that the problem with students not 
appreciating the need for style or readability is implicit within the 
traditional 'work by yourself, and for yourself' methods of schooling 
(this is changing); and how, to demand apparently-abstract adherence to 
standards or convention would create an apposite relationship between 
teacher and student. No doubt! Confirming this admission of defeat, the 
chapter on "Style" is sandwiched between two entitled, "Coding Tricks" 
and "More Coding Tricks".

However, professionals would say that coding-style cannot be ignored. 
Accordingly most trainers attempt to model 'best-practice' in our 
training materials. Sadly, the reality is that a good docstring for a 
toy-example may be longer than the actual code. Thus, such ideals may 
actually interfere with the learning process. Exigencies apply! 
Therefore, one of the book's (and the class's) missed-opportunities is 
that professionals (and students) may only ever convince themselves of 
such a need, after 'suffering' through reading and maintaining/improving 
others' code - at which point we 'discover' the struggles of 
wading-through a 'tangled mess'. (Perhaps a message to all of us?)

There is a useful chapter on Testing, followed by four weakly-justified 
pages on Defensive Programming. However, the TDD (and others) approach 
of separating code from test modules is not mentioned. Debug-prints are 
favored over debuggers. Scaffolding "which will be removed eventually" 
is recommended, despite the virtue of test-runners remaining available 
for future use.

There is a nod towards Numerical Analysis in coverage of the 'dangers' 
inherent in floating-point computation, which many would be wise to 
absorb! Unfortunately, this content will not encourage or extend your 
experience into Python's Decimal library. The math-bias shows in the 
strength of algorithmic coverage, and the dearth of data considerations. 
Even Data Scientists preface their analyses with data-collection, and 
data-cleaning processes! Within an environment concentrating on 
implementing algorithms with simple (and tailored) data formats, such a 
view may be justifiable.

Object-Oriented Programming receives short-shrift, which is likely 
appropriate, given the examples' subject-matter, and the lack of (need 
for, teaching-approach using) re-use. Sadly, in a discussion of the 
'Traveling Salesman Problem' he recommends a complex structure of 
mutable lists for x,y co-ordinates to which id-s (pointers) are added. 
Whereas, a custom class would simplify understanding and better relieve 
the loss of "control" (of the code-solution) he describes. Some will 
support the chapter "Beware of OOP", whilst others recoil in horror. 
Again, a divergence between ComSc and industry, and a predilection for 
edge-cases seem to justify the author's views. The many advantages 
built-in to popular Python IDEs are also a missed opportunity. Likewise, 
GUI and web interfaces are not discussed. That said, time is devoted to 
building speed-tests as means of refinement and an aid to refactoring.

To be fair, it is not easy to convince high school students, or for that 
matter many neophyte programmers, of the virtues of 'industry 
standards', eg avoiding 'clever code' to enhance readability. Which 
implies that the title of the book is too general and requires a more 
descriptive (and accurate) sub-title, eg "for High School Computing". 
Further, to be true to the comparisons drawn in "Expert Advice", the 
book's sub-title should replace its current "Programming Skills" with 
the term "Computer Science", thus justifying the author's view that 
"professional software developers work in a significantly different 
world from the C.S. student. ...team...legacy code...end 
users...convenient interfaces...consistency" contrasting radically with 
"code up algorithms that will be run one time in front of the teacher".

This book's title is a publisher's marketing-masterpiece of community 
appeal. However, the content fails to deliver on the promise. If you 
seek advice about professional practice, or to improve Python skills, 
look elsewhere. If you are a High School student considering IT as a 
career, look elsewhere. However, if you are a math-based, ComSc student 
(including, perhaps, first-year University Under-Graduates) and you're 
studying algorithms, this book includes much food-for-thought.


The reviewer's first degree included a ComSc major. He has worked in IT 
and business for decades, and is an international consultant and 
vocational trainer.

-- 
Regards,
=dn

From royskanti at gmail.com  Thu Jun 25 23:46:15 2020
From: royskanti at gmail.com (SUMAN KANTI ROY)
Date: Fri, 26 Jun 2020 09:16:15 +0530
Subject: [Tutor] column heading
Message-ID: <CAF2nR5VbsG2TAvvtiUG2Zi1cnbd4gdcxNhyYrbG9grdtBM8DJA@mail.gmail.com>

a=[1,2,3,4,5,6,7,8,9,10]
arr=[[1,2],[2,23],[4,5]]
dic={}
for i in range(0,len(arr)):
    if arr[i][0] not in dic:
        dic[arr[i][0]]=arr[i][1]
arr1=[]
def find_key(val,dic):
    for i in dic.keys():
        if dic[i]==val:
            return i
new_arr=sorted(dic.values(),reverse=True)
ans= [[0 for i in range(3)] for i in range(len(new_arr))]
for i in range(len(new_arr)):
    ans[i][0]=a[i]
    ans[i][1]=find_key(new_arr[i],dic)
    ans[i][2]=new_arr[i]
print(ans)

0/p=====[[1, 2, 23], [2, 4, 5], [3, 1, 2]]
I want to make it 3 column matrix ,,,with column heading
name['device',R.B.N','CQI']
please guide me...

From alan.gauld at yahoo.co.uk  Fri Jun 26 04:34:46 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 26 Jun 2020 09:34:46 +0100
Subject: [Tutor] column heading
In-Reply-To: <CAF2nR5VbsG2TAvvtiUG2Zi1cnbd4gdcxNhyYrbG9grdtBM8DJA@mail.gmail.com>
References: <CAF2nR5VbsG2TAvvtiUG2Zi1cnbd4gdcxNhyYrbG9grdtBM8DJA@mail.gmail.com>
Message-ID: <rd4bv6$3g6e$1@ciao.gmane.io>

On 26/06/2020 04:46, SUMAN KANTI ROY wrote:
> a=[1,2,3,4,5,6,7,8,9,10]
> arr=[[1,2],[2,23],[4,5]]
> dic={}
> for i in range(0,len(arr)):
>     if arr[i][0] not in dic:
>         dic[arr[i][0]]=arr[i][1]

Any time you see yourself writing code like this
you should give yourself a hard slap! Its virtually
never the right thing to do in Python. Even if you
need the index you can use enumerate(). But usually
you don't even need that.

In this case you can use variable unpacking to write:

for a,b in arr:
   if a not in dic:
      dic[a] = b

Which is significantly easier to read, and debug.

> arr1=[]
> def find_key(val,dic):
>     for i in dic.keys():
>         if dic[i]==val:
>             return i

Similarly here, if you use dic.items instead of
keys you can avoid indexing.

for k,v in dic.items():
    if val == v:
       return k

> new_arr=sorted(dic.values(),reverse=True)

ok...

> ans= [[0 for i in range(3)] for i in range(len(new_arr))]
> for i in range(len(new_arr)):
>     ans[i][0]=a[i]
>     ans[i][1]=find_key(new_arr[i],dic)
>     ans[i][2]=new_arr[i]

ans = ['device, 'R B N', 'CQI']
for index,item in enumerate(new_arr):
    ans.append([ a[index],   # probably a better way of doing this
                 find_key(item,dic),
                 item])

> I want to make it 3 column matrix ,,,with column heading
> name['device',R.B.N','CQI']

Try to avoid using indexes they are error prone and hard to
read or debug.

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 PyTutor at danceswithmice.info  Fri Jun 26 05:33:19 2020
From: PyTutor at danceswithmice.info (dn)
Date: Fri, 26 Jun 2020 21:33:19 +1200
Subject: [Tutor] column heading
In-Reply-To: <CAF2nR5VbsG2TAvvtiUG2Zi1cnbd4gdcxNhyYrbG9grdtBM8DJA@mail.gmail.com>
References: <CAF2nR5VbsG2TAvvtiUG2Zi1cnbd4gdcxNhyYrbG9grdtBM8DJA@mail.gmail.com>
Message-ID: <bdd2caf6-cd00-d44c-2c5e-75b353bf0c49@DancesWithMice.info>

On 26/06/20 3:46 PM, SUMAN KANTI ROY wrote:
> a=[1,2,3,4,5,6,7,8,9,10]
> arr=[[1,2],[2,23],[4,5]]
> dic={}
> for i in range(0,len(arr)):
>      if arr[i][0] not in dic:
>          dic[arr[i][0]]=arr[i][1]
> arr1=[]
> def find_key(val,dic):
>      for i in dic.keys():
>          if dic[i]==val:
>              return i
> new_arr=sorted(dic.values(),reverse=True)
> ans= [[0 for i in range(3)] for i in range(len(new_arr))]
> for i in range(len(new_arr)):
>      ans[i][0]=a[i]
>      ans[i][1]=find_key(new_arr[i],dic)
>      ans[i][2]=new_arr[i]
> print(ans)
> 
> 0/p=====[[1, 2, 23], [2, 4, 5], [3, 1, 2]]
> I want to make it 3 column matrix ,,,with column heading
> name['device',R.B.N','CQI']
> please guide me...


As @Alan has said, you are trying to write Java/C/? in Python. The 
Python language has its own idioms and techniques. I'm also going to 
criticise the choice of variable_names - and Python uses "lists" not 
"arrays"!

Here is some food for thought (and there are other ways of achieving the 
same):

- because the array is a list of 2-member lists you can use Python's 
dynamic conversions:

 >>> arr=[[1,2],[2,23],[4,5]]
 >>> dic = dict( arr )
 >>> dic
{1: 2, 2: 23, 4: 5}

- each element of a dictionary consists of a key and a value. They can 
be considered separately:

 >>> keys = dic.keys()
 >>> keys
dict_keys([1, 2, 4])
 >>> values = dic.values()

- two lists can be joined - except that the basic result is an iterator:

 >>> inverted_arr = list( zip( dic.values(), dic.keys() ) )
 >>> inverted_arr
[(2, 1), (23, 2), (5, 4)]

- and just to complete the picture, we do the list-to-dict 'trick' again:

 >>> inverted_dic = dict( inverted_arr )
 >>> inverted_dic
{2: 1, 23: 2, 5: 4}

- which has generated all of the constructs needed!

I'll leave it to you to decide if you need the inverted dict. Research 
the Python documentation (it's very good!), and note that zip() allows 
multiple lists to be zip-ped together, providing...

Can you now solve the problem without using any for-loops?
-- 
Regards =dn

From savageapple850 at gmail.com  Fri Jun 26 10:25:32 2020
From: savageapple850 at gmail.com (Cravan)
Date: Fri, 26 Jun 2020 22:25:32 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
Message-ID: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>

Sadly, an error pops up when I change the code.
Here's my edited code for the class file:
````
class Zomb(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites, game.zombs
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = game.zomb_img
        self.rect = self.image.get_rect()
        #image = image provided in game
        self.x = x
        self.y = y
        self.pos = (x, y)
        #this is each state
        #possible states
        for a in range(int(GRIDWIDTH)):
            for b in range(int(GRIDHEIGHT)):
                self.stateSpace = [(a,b)]
        self.actionSpace = {'U': - 1, 'D': 1,
                            'L': - 1, 'R': 1}
        #corresponding adjustments
        self.possibleActions = ['U', 'D', 'L', 'R']
        #list of possible actions
        self.vel = 0
        self.acc = 0
        self.rect.center = vec(self.x, self.y)
        self.rotate = 0

    def setState(self, state):
        self.pos = state

    def TerminalState(self, state):
        if self.game.health == 0:
            return True
        else:
            return False

    def step(self, action):
        x, y = self.x, self.y
        if self.actionSpace[action] == 'U':
            self.y = self.y + 1
        elif self.actionSpace[action] == 'D':
            self.y = self.y - 1
        elif self.actionSpace[action] == 'R':
            self.x = self.x + 1
        elif self.actionSpace[action] == 'L':
            self.x = self.x - 1
        resultingState = (self.x, self.y)
        self.game.reward = -1 if not self.TerminalState(resultingState) else 0
        self.setState(resultingState)


        return resultingState, self.game.reward,\
            self.TerminalState(resultingState), None

    def actionSpaceSample(self):
        return np.random.choice(self.possibleActions)

    def update(self):
        self.rotate = (self.game.player.pos - self.rect.center).angle_to(vec(1, 0))
        self.image = self.game.zomb_img
        self.rect = self.image.get_rect()
        self.acc = vec(ZOMB_SPEED, 0).rotate(-self.rotate)
````
And here's my edited main implementation now in the update() function:
```
ALPHA = 0.1
        GAMMA = 1.0
        EPS = 1.0
        Q = {}

        for zomb in self.zombs:
            print(zomb.stateSpace)
            for state in zomb.stateSpace:
                for action in zomb.possibleActions:
                    Q[state, action] = 0
        numGames = 10
        totalRewards = np.zeros(numGames)
        for i in range(numGames):

            print('starting game ', i + 1)
            epRewards = 0

        rand = np.random.random()
        for zomb in self.zombs:
            observation = zomb.pos
            #state
            action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \
                                                        else zomb.actionSpaceSample()
            #choosing the best action possible

            observationnew, reward, done, info = zomb.step(action)
        epRewards += reward

        for zomb in self.zombs:
            possible_actions = zomb.possibleActions
            action_ = maxAction(Q, observationnew, possible_actions)

        Q[observation,action] = Q[observation,action] + ALPHA*(reward + \
                    GAMMA*Q[observationnew,action_] - Q[observation,action])
        observation = observationnew
        if EPS - 2 / numGames > 0:
            EPS -= 2 / numGames
        else:
            EPS = 0
        totalRewards[i] = epRewards
```
However, this error pops up:
#######
Traceback (most recent call last):
  File "maze.py", line 181, in <module>
    g.run()
  File "maze.py", line 53, in run
    self.update()
  File "maze.py", line 109, in update
    action_ = maxAction(Q, observationnew, possible_actions)
  File "maze.py", line 177, in maxAction
    values = np.array([Q[state,a] for a in actions])
  File "maze.py", line 177, in <listcomp>
    values = np.array([Q[state,a] for a in actions])
KeyError: ((6, 26), 'U')
######

Apologies for the (late) and long email here, would appreciate if someone could offer some help.

Thanks,
Cravan

?On 26/6/20, 12:18 AM, "Tutor on behalf of Mats Wichmann" <tutor-bounces+savageapple850=gmail.com at python.org on behalf of mats at wichmann.us> wrote:

    On 6/25/20 10:06 AM, Mats Wichmann wrote:
    
    sigh... think one thing, write another:
    
    > Your Q is a dictionary;
    > 
    >     Q = {}
    > 
    > and dicts specifically have the restriction that the type be hashable
    
    ... that the _key_ be hashable ...
    _______________________________________________
    Tutor maillist  -  Tutor at python.org
    To unsubscribe or change subscription options:
    https://mail.python.org/mailman/listinfo/tutor
    



From john at johnweller.co.uk  Fri Jun 26 06:21:02 2020
From: john at johnweller.co.uk (John Weller)
Date: Fri, 26 Jun 2020 11:21:02 +0100
Subject: [Tutor] Running Python Scripts at same time
Message-ID: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>

I have a Python program which will be running 24/7 (I hope ?).  It is generating data in a file which I want to clean up overnight.  The way I am looking at doing it is to run a separate program as a Cron job at midnight ? will that work?  The alternative is to add it to the loop and check for the time. I have tried researching this but only got even more confused.

 

Thanks

 

John

 

John Weller

01380 723235

07976 393631

 


From alan.gauld at yahoo.co.uk  Fri Jun 26 10:38:22 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 26 Jun 2020 15:38:22 +0100
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
Message-ID: <rd518u$9vo$1@ciao.gmane.io>

On 26/06/2020 11:21, John Weller wrote:
> I have a Python program which will be running 24/7 (I hope ?).  > It is generating data in a file which I want to clean up overnight.
> The way I am looking at doing it is to run a separate program 
> as a Cron job at midnight ? will that work? 

Yes, there is no limit to how many concurrent python sessions you
run.(Apart from the capacity of your computer of courses)

But it will be a completely separate program. It will have no
access to the variables or state of your original program.
You won't for example be able to tell whether the original
program is writing to the file at the time you want to
delete it. You will need to ensure that the code of each
is robust enough to handle that.

The usual way of dealing with that is to get the first program
to write to a file whose name incorporates the date. Then it
will automatically create a new file each day. Your second
program can then do what it wishes with the previous days
file, certain that the first won't be interfering with it.

-- 
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 Jun 26 10:41:48 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Fri, 26 Jun 2020 08:41:48 -0600
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
 <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
Message-ID: <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us>

On 6/26/20 8:25 AM, Cravan wrote:
> Sadly, an error pops up when I change the code.
> Here's my edited code for the class file:

> However, this error pops up:
> #######
> Traceback (most recent call last):
>   File "maze.py", line 181, in <module>
>     g.run()
>   File "maze.py", line 53, in run
>     self.update()
>   File "maze.py", line 109, in update
>     action_ = maxAction(Q, observationnew, possible_actions)
>   File "maze.py", line 177, in maxAction
>     values = np.array([Q[state,a] for a in actions])
>   File "maze.py", line 177, in <listcomp>
>     values = np.array([Q[state,a] for a in actions])
> KeyError: ((6, 26), 'U')
> ######
> 
> Apologies for the (late) and long email here, would appreciate if someone could offer some help.
Well, again the error tells you what is happening: KeyError means you
tried to look up a key in a dictionary that is actually not present in
the dictionary.

So Q does not contain the tuple  ((6, 26), 'U')

only you can tell if that's a legitimate result, or an unexpected one.

if it's *expected* that there will be some mismatches, you can do this:

try:
    values = np.array([Q[state,a] for a in actions])
except KeyError:
    # take appropriate action for missing key

If it's unexpected, then you have some recoding to do.

From savageapple850 at gmail.com  Fri Jun 26 11:00:58 2020
From: savageapple850 at gmail.com (Cravan)
Date: Fri, 26 Jun 2020 23:00:58 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
 <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
 <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us>
Message-ID: <9686CFFE-0C15-4EDE-859A-A4C12DB82465@gmail.com>

Hi Mats,
	Sorry for the late reply. Thanks for your suggestion, I realised that Q was merely giving only some values due to my class settings. However, I have no idea how to set all the coordinates as my state Space. Assuming WIDTH and HEIGHT are the width and height of my env respectively, how should I define my state space within the class itself?
Something like this (although this is wrong) :
 self.stateSpace = [(i for i in range(int(WIDTH)), q for q in range(int(HEIGHT)))]

Essentially my logic is for each number in range(Width), pair it to a number in range(HEIGHT). How should I rectify the code above so as to fit my logic while also conforming to "Pythonic" laws?
Cravan

?On 26/6/20, 10:43 PM, "Tutor on behalf of Mats Wichmann" <tutor-bounces+savageapple850=gmail.com at python.org on behalf of mats at wichmann.us> wrote:

    On 6/26/20 8:25 AM, Cravan wrote:
    > Sadly, an error pops up when I change the code.
    > Here's my edited code for the class file:
    
    > However, this error pops up:
    > #######
    > Traceback (most recent call last):
    >   File "maze.py", line 181, in <module>
    >     g.run()
    >   File "maze.py", line 53, in run
    >     self.update()
    >   File "maze.py", line 109, in update
    >     action_ = maxAction(Q, observationnew, possible_actions)
    >   File "maze.py", line 177, in maxAction
    >     values = np.array([Q[state,a] for a in actions])
    >   File "maze.py", line 177, in <listcomp>
    >     values = np.array([Q[state,a] for a in actions])
    > KeyError: ((6, 26), 'U')
    > ######
    > 
    > Apologies for the (late) and long email here, would appreciate if someone could offer some help.
    Well, again the error tells you what is happening: KeyError means you
    tried to look up a key in a dictionary that is actually not present in
    the dictionary.
    
    So Q does not contain the tuple  ((6, 26), 'U')
    
    only you can tell if that's a legitimate result, or an unexpected one.
    
    if it's *expected* that there will be some mismatches, you can do this:
    
    try:
        values = np.array([Q[state,a] for a in actions])
    except KeyError:
        # take appropriate action for missing key
    
    If it's unexpected, then you have some recoding to do.
    _______________________________________________
    Tutor maillist  -  Tutor at python.org
    To unsubscribe or change subscription options:
    https://mail.python.org/mailman/listinfo/tutor
    



From PyTutor at danceswithmice.info  Fri Jun 26 20:12:54 2020
From: PyTutor at danceswithmice.info (dn)
Date: Sat, 27 Jun 2020 12:12:54 +1200
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
 <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
Message-ID: <d4fbe4e0-3ef2-c047-c66b-16afb7661661@DancesWithMice.info>

On 27/06/20 2:25 AM, Cravan wrote:
> Sadly, an error pops up when I change the code.
> Here's my edited code for the class file:
> ````
> class Zomb(pg.sprite.Sprite):
>      def __init__(self, game, x, y):
>          self.groups = game.all_sprites, game.zombs
>          pg.sprite.Sprite.__init__(self, self.groups)
>          self.game = game
>          self.image = game.zomb_img
>          self.rect = self.image.get_rect()
>          #image = image provided in game
>          self.x = x
>          self.y = y
>          self.pos = (x, y)
>          #this is each state
>          #possible states
>          for a in range(int(GRIDWIDTH)):
>              for b in range(int(GRIDHEIGHT)):
>                  self.stateSpace = [(a,b)]
>          self.actionSpace = {'U': - 1, 'D': 1,
>                              'L': - 1, 'R': 1}
>          #corresponding adjustments
>          self.possibleActions = ['U', 'D', 'L', 'R']
>          #list of possible actions
>          self.vel = 0
>          self.acc = 0
>          self.rect.center = vec(self.x, self.y)
>          self.rotate = 0
> 
>      def setState(self, state):
>          self.pos = state
> 
>      def TerminalState(self, state):
>          if self.game.health == 0:
>              return True
>          else:
>              return False
> 
>      def step(self, action):
>          x, y = self.x, self.y
>          if self.actionSpace[action] == 'U':
>              self.y = self.y + 1
>          elif self.actionSpace[action] == 'D':
>              self.y = self.y - 1
>          elif self.actionSpace[action] == 'R':
>              self.x = self.x + 1
>          elif self.actionSpace[action] == 'L':
>              self.x = self.x - 1
>          resultingState = (self.x, self.y)
>          self.game.reward = -1 if not self.TerminalState(resultingState) else 0
>          self.setState(resultingState)
> 
> 
>          return resultingState, self.game.reward,\
>              self.TerminalState(resultingState), None
> 
>      def actionSpaceSample(self):
>          return np.random.choice(self.possibleActions)
> 
>      def update(self):
>          self.rotate = (self.game.player.pos - self.rect.center).angle_to(vec(1, 0))
>          self.image = self.game.zomb_img
>          self.rect = self.image.get_rect()
>          self.acc = vec(ZOMB_SPEED, 0).rotate(-self.rotate)
> ````
> And here's my edited main implementation now in the update() function:
> ```
> ALPHA = 0.1
>          GAMMA = 1.0
>          EPS = 1.0
>          Q = {}
> 
>          for zomb in self.zombs:
>              print(zomb.stateSpace)
>              for state in zomb.stateSpace:
>                  for action in zomb.possibleActions:
>                      Q[state, action] = 0
>          numGames = 10
>          totalRewards = np.zeros(numGames)
>          for i in range(numGames):
> 
>              print('starting game ', i + 1)
>              epRewards = 0
> 
>          rand = np.random.random()
>          for zomb in self.zombs:
>              observation = zomb.pos
>              #state
>              action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \
>                                                          else zomb.actionSpaceSample()
>              #choosing the best action possible
> 
>              observationnew, reward, done, info = zomb.step(action)
>          epRewards += reward
> 
>          for zomb in self.zombs:
>              possible_actions = zomb.possibleActions
>              action_ = maxAction(Q, observationnew, possible_actions)
> 
>          Q[observation,action] = Q[observation,action] + ALPHA*(reward + \
>                      GAMMA*Q[observationnew,action_] - Q[observation,action])
>          observation = observationnew
>          if EPS - 2 / numGames > 0:
>              EPS -= 2 / numGames
>          else:
>              EPS = 0
>          totalRewards[i] = epRewards
> ```
> However, this error pops up:
> #######
> Traceback (most recent call last):
>    File "maze.py", line 181, in <module>
>      g.run()
>    File "maze.py", line 53, in run
>      self.update()
>    File "maze.py", line 109, in update
>      action_ = maxAction(Q, observationnew, possible_actions)
>    File "maze.py", line 177, in maxAction
>      values = np.array([Q[state,a] for a in actions])
>    File "maze.py", line 177, in <listcomp>
>      values = np.array([Q[state,a] for a in actions])
> KeyError: ((6, 26), 'U')
> ######


It may be worth taking a step-back - both in terms of the design you are 
implementing and the questions you are asking of us:-

Have looked and looked, and then used 'find', but failed to find the 
code-line at-error. Why? [help us to help you!]

Aside from learning Python's idioms, are you using a competent IDE? 
Could you then use full-names instead of abbreviations, without adding 
major effort? I think we could guess what a "zomb" is, but would it be 
better (and kinder) to remove all doubt?

Have comments and "docstrings" (a pythonic idiom) been used to describe 
what the code/each function is supposed to do, and why?

If the game's environment is described as a "grid", why is its width and 
height described using anything other than int[eger]s?

What is the purpose of "state"? Is there a difference between "state" 
and "position" (or next-/previous-position)?

Have you understood the (animation) concept of collision? (assuming that 
is part of the intent here) Have you noted various algorithms and 
approximations which are commonly-used?
-- 
Regards =dn

From bouncingcats at gmail.com  Fri Jun 26 21:35:57 2020
From: bouncingcats at gmail.com (David)
Date: Sat, 27 Jun 2020 11:35:57 +1000
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
Message-ID: <CAMPXz=pMbLCBRh4BTFo_duaKrJ4XLuisqwwvXcWdZDOtCGg6-A@mail.gmail.com>

On Sat, 27 Jun 2020 at 00:32, John Weller <john at johnweller.co.uk> wrote:

I have a Python program which will be running 24/7 (I hope ?).  It is
> generating data in a file which I want to clean up overnight.  The way I am
> looking at doing it is to run a separate program as a Cron job at midnight
> ? will that work?  The alternative is to add it to the loop and check for
> the time.
>

Hi, can you more fully describe the complete situation? I just have a hunch
that you haven't given enough information to generate very helpful replies.

How much data is involved? How quickly does it accumulate? Why do you want
to clean it "overnight", does it go to sleep? What is the hardware and OS
platform?

Also, can you explain why you believe that whatever "cleaning" you need
must be done by a separate program? Because that is a rather important
design decision with many consequences.

I guess you have your reasons, but you haven't shared them or the big
picture with us. Without that information, this reads like a classic "XY"
question: https://en.wikipedia.org/wiki/XY_problem

The problem with that kind of question is that it restricts the ability of
people to assist you.

I suggest that if you give the bigger picture then that will increase the
scope for people here to offer educational and useful replies, the reason
why the *tutor* list exists.

> I have tried researching this but only got even more confused.

People here are pretty good at offering great guidance, if you describe the
problem fully. Try not to narrow the solution space because of your own
confusion.

I write this advice from the perspective of someone who mostly reads this
list to learn. In this case I don't expect to have any answers, but I hope
that if you describe what you are doing more completely, then that will
create an opportunity for others to share their expertise in Python or data
acquisition or concurrent processing or whatever else with all of us.

From savageapple850 at gmail.com  Fri Jun 26 21:44:26 2020
From: savageapple850 at gmail.com (Cravan)
Date: Sat, 27 Jun 2020 09:44:26 +0800
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <d4fbe4e0-3ef2-c047-c66b-16afb7661661@DancesWithMice.info>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
 <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
 <d4fbe4e0-3ef2-c047-c66b-16afb7661661@DancesWithMice.info>
Message-ID: <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com>



?> On 27/6/20, 8:13 AM, "Tutor on behalf of dn via Tutor" <tutor-bounces+savageapple850=gmail.com at python.org on behalf of tutor at python.org> wrote:

  	
    > It may be worth taking a step-back - both in terms of the design you are 
    implementing and the questions you are asking of us:-
Sure! I apologise for any inconvenience caused, and really appreciate your efforts to help me    
    > Have looked and looked, and then used 'find', but failed to find the 
    code-line at-error. Why? [help us to help you!]
Essentially right now my dictionary is only churning out values of a current index when printing it out, so e.g.
{((1023, 767), 'U'): 0, ((1023, 767), 'D'): 0, ((1023, 767), 'L'): 0, ((1023, 767), 'R'): 0} when it's supposed to be inclusive of all the coords. in the game (and the possible actions). I can't seem to rectify it(I don't know how).
    
    > Aside from learning Python's idioms, are you using a competent IDE? 
    Could you then use full-names instead of abbreviations, without adding 
    major effort? I think we could guess what a "zomb" is, but would it be 
    better (and kinder) to remove all doubt?
I'm using Atom to do it. An enemy in this case would be a zombie.(zomb) who is seeking to kill the player. The player has a health bar which decreases when the zombie touches it, and my game is a maze game. The zombies can pass through walls to give them an advantage over the player (making it more difficult)
    >  Have comments and "docstrings" (a pythonic idiom) been used to describe 
    what the code/each function is supposed to do, and why?
Well, some (haha). 
    
    > If the game's environment is described as a "grid", why is its width and 
    height described using anything other than int[eger]s?
Width and Height are the actual width and height. Essentially gridwidth and gridheight are the width and height (in tilesize units) e.g. 3 tiles x 4 tiles for example
    > What is the purpose of "state"? Is there a difference between "state" 
    and "position" (or next-/previous-position)?
A state is essentially the current state of the system (i.e. I can set the state as the product of my coordinates, for example but now I'm using it as the coords. for convenience), within a set of states (product of the maximum y-coord and the max. x-coord but it also can be all the coords in my environment(which I am using))
    
    > Have you understood the (animation) concept of collision? (assuming that 
    is part of the intent here) Have you noted various algorithms and 
    approximations which are commonly-used?
Yes, the collision part is fine since I was able to get it to work before the implementation of machine learning
    -- 
    Regards =dn
    _______________________________________________
    Tutor maillist  -  Tutor at python.org
    To unsubscribe or change subscription options:
    https://mail.python.org/mailman/listinfo/tutor
    



From jf_byrnes at comcast.net  Sat Jun 27 12:44:09 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 11:44:09 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
Message-ID: <rd7t0r$2ccf$1@ciao.gmane.io>

I am writing a script that will delete unwanted cookies from the Firefox 
cookies.sqlite file  based on a white list. I found that I could not 
connect to the file in my profile directory when Firefox is active. If I 
copy cookies.sqlite to a temporary location the script will connect to 
the db and delete unwanted cookies.

The problem is when I copy the file back to my profile directory and use 
preferences to check for cookies, the deleted cookies have reappeared. 
This seems to be the result of a file called cookies.sqlite-wal in the 
same directory.

More info on sqlite-wal here: https://sqlite.org/wal.html

Based on what I read in the above link and some googling it looked like 
the cookies.sqlite-wal file had not yet updated the cookies.sqlite file.
So I copied the cookies.sqlite file and looked at it with a db viewer 
and the cookies I wanted to delete were not there. So I copied the 
cookies.sqlite-wal file to the same location and then ran this portion 
of the script and the cookies appeared in the db.

def sqlite3Connect():
     ''' Connect to cookies database '''
     conn = sqlite3.connect(WORK_AREA + "cookies.sqlite")
     conn.execute('PRAGMA wal_checkpoint(TRUNCATE)')
     return conn

Checking the db the cookies I wanted to delete were now in the db. I 
then ran the part of the script that deleted the cookies. After running 
the db viewer I could see the cookies had been deleted. However when I 
deleted the cookies.sqlite and cookes.sqlite-wal files from my firefox 
profile and copied my updated cookies.sqlite file to my profile, 
checking with firefox still showed the cookies I tried to delete.

At this point I am out of ideas and wondering if anyone knows how to 
successfully manipulate this file?

Thanks,  Jim


From alan.gauld at yahoo.co.uk  Sat Jun 27 13:03:16 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 27 Jun 2020 18:03:16 +0100
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd7t0r$2ccf$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io>
Message-ID: <rd7u4k$or8$1@ciao.gmane.io>

On 27/06/2020 17:44, Jim wrote:

> The problem is when I copy the file back to my profile directory and use 
> preferences to check for cookies, the deleted cookies have reappeared. 
> This seems to be the result of a file called cookies.sqlite-wal in the 
> same directory.

I assume you are closing all instances of Firefox down before copying
the new file into place? Otherwise Firefox is probably overwriting it
from a cache in memory or somesuch.

-- 
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  Sat Jun 27 14:02:45 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 13:02:45 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd7u4k$or8$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
Message-ID: <rd81k6$4t9$1@ciao.gmane.io>

On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote:
> On 27/06/2020 17:44, Jim wrote:
> 
>> The problem is when I copy the file back to my profile directory and use
>> preferences to check for cookies, the deleted cookies have reappeared.
>> This seems to be the result of a file called cookies.sqlite-wal in the
>> same directory.
> 
> I assume you are closing all instances of Firefox down before copying
> the new file into place? Otherwise Firefox is probably overwriting it
> from a cache in memory or somesuch.
> 

No I am trying to do it without shutting down Firefox. I normally have 3 
instances of Firefox open. 2 private and 1 normal. It's the normal one I 
am working on. At the end of the day I manually remove cookies I don't 
want so I am trying to automate the process. If I had to manually shut 
down all instances Firefox it would defeat the purpose of automation. If 
I can't find another solution I may try to just programmatically shut 
down the normal one, the private ones normally have multiple tabs open 
and I don't want to close them. Years ago I had a problem with Firefox 
crashing when trying to reopen tabs and since then I have always turned 
that setting off.

Regards,  Jim


From robertvstepp at gmail.com  Sat Jun 27 14:10:57 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 27 Jun 2020 13:10:57 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd81k6$4t9$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
Message-ID: <CANDiX9KEae0hw+WKQAhQCJpkk_RndLNhUdYcnsfO1_EYcTR7mg@mail.gmail.com>

On Sat, Jun 27, 2020 at 1:02 PM Jim <jf_byrnes at comcast.net> wrote:
> ... Years ago I had a problem with Firefox
> crashing when trying to reopen tabs and since then I have always turned
> that setting off.

Perhaps this has been improved in current versions of Firefox?  I have
yet to experience this issue since I have switched to Firefox about
two or three years ago.  My tabs have always been seamlessly restored
for multiple instances of Firefox windows open.


-- 
boB

From Richard at Damon-Family.org  Sat Jun 27 14:16:54 2020
From: Richard at Damon-Family.org (Richard Damon)
Date: Sat, 27 Jun 2020 14:16:54 -0400
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd81k6$4t9$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
Message-ID: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>

On 6/27/20 2:02 PM, Jim wrote:
> On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote:
>> On 27/06/2020 17:44, Jim wrote:
>>
>>> The problem is when I copy the file back to my profile directory and
>>> use
>>> preferences to check for cookies, the deleted cookies have reappeared.
>>> This seems to be the result of a file called cookies.sqlite-wal in the
>>> same directory.
>>
>> I assume you are closing all instances of Firefox down before copying
>> the new file into place? Otherwise Firefox is probably overwriting it
>> from a cache in memory or somesuch.
>>
>
> No I am trying to do it without shutting down Firefox. I normally have
> 3 instances of Firefox open. 2 private and 1 normal. It's the normal
> one I am working on. At the end of the day I manually remove cookies I
> don't want so I am trying to automate the process. If I had to
> manually shut down all instances Firefox it would defeat the purpose
> of automation. If I can't find another solution I may try to just
> programmatically shut down the normal one, the private ones normally
> have multiple tabs open and I don't want to close them. Years ago I
> had a problem with Firefox crashing when trying to reopen tabs and
> since then I have always turned that setting off.
>
> Regards,? Jim

Just because a program uses a sqlite database, doesn't mean that it
intends for you to be able to interact with it by changing that
database. You are probably locked out of directly operating on it by the
program having a write lock on the database, thus blocking you from
updating it.

Deleting the file and replacing with the database open is one of the
items on the list of how to corrupt your database. Likely the pages with
the cookies are in program cache memory, and spooled out at some point
when updated.

I would look at writing a Firefox extension to do the cookie cleanup (if
there isn't one already that does a close enough job) rather than
something outside of Firefox.

-- 
Richard Damon


From jf_byrnes at comcast.net  Sat Jun 27 14:23:05 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 13:23:05 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <CANDiX9KEae0hw+WKQAhQCJpkk_RndLNhUdYcnsfO1_EYcTR7mg@mail.gmail.com>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <CANDiX9KEae0hw+WKQAhQCJpkk_RndLNhUdYcnsfO1_EYcTR7mg@mail.gmail.com>
Message-ID: <rd82q9$2lc2$1@ciao.gmane.io>

On 6/27/20 1:10 PM, boB Stepp wrote:
> On Sat, Jun 27, 2020 at 1:02 PM Jim <jf_byrnes at comcast.net> wrote:
>> ... Years ago I had a problem with Firefox
>> crashing when trying to reopen tabs and since then I have always turned
>> that setting off.
> 
> Perhaps this has been improved in current versions of Firefox?  I have
> yet to experience this issue since I have switched to Firefox about
> two or three years ago.  My tabs have always been seamlessly restored
> for multiple instances of Firefox windows open.
> 
> 

That's probably true but I guess old habits die hard.

Regards,  Jim


From jf_byrnes at comcast.net  Sat Jun 27 14:31:30 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 13:31:30 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
Message-ID: <rd83a3$3kuq$1@ciao.gmane.io>

On 6/27/20 1:16 PM, Richard Damon wrote:
> On 6/27/20 2:02 PM, Jim wrote:
>> On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote:
>>> On 27/06/2020 17:44, Jim wrote:
>>>
>>>> The problem is when I copy the file back to my profile directory and
>>>> use
>>>> preferences to check for cookies, the deleted cookies have reappeared.
>>>> This seems to be the result of a file called cookies.sqlite-wal in the
>>>> same directory.
>>>
>>> I assume you are closing all instances of Firefox down before copying
>>> the new file into place? Otherwise Firefox is probably overwriting it
>>> from a cache in memory or somesuch.
>>>
>>
>> No I am trying to do it without shutting down Firefox. I normally have
>> 3 instances of Firefox open. 2 private and 1 normal. It's the normal
>> one I am working on. At the end of the day I manually remove cookies I
>> don't want so I am trying to automate the process. If I had to
>> manually shut down all instances Firefox it would defeat the purpose
>> of automation. If I can't find another solution I may try to just
>> programmatically shut down the normal one, the private ones normally
>> have multiple tabs open and I don't want to close them. Years ago I
>> had a problem with Firefox crashing when trying to reopen tabs and
>> since then I have always turned that setting off.
>>
>> Regards,? Jim
> 
> Just because a program uses a sqlite database, doesn't mean that it
> intends for you to be able to interact with it by changing that
> database. You are probably locked out of directly operating on it by the
> program having a write lock on the database, thus blocking you from
> updating it.

I'm sure that is the case and is why I tried moving it.

> Deleting the file and replacing with the database open is one of the
> items on the list of how to corrupt your database. Likely the pages with
> the cookies are in program cache memory, and spooled out at some point
> when updated.

I didn't mention it but I do have a copy of both files right after I 
manually cleaned them from inside Firefox.

> I would look at writing a Firefox extension to do the cookie cleanup (if
> there isn't one already that does a close enough job) rather than
> something outside of Firefox.

I know I don't have the expertise to do that. Having to manually delete 
some cookies is not a big deal, I just enjoy programing with Python so I 
look for things I can automate.

Regards,  Jim
> 



From mats at wichmann.us  Sat Jun 27 14:33:12 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 27 Jun 2020 12:33:12 -0600
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd82q9$2lc2$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <CANDiX9KEae0hw+WKQAhQCJpkk_RndLNhUdYcnsfO1_EYcTR7mg@mail.gmail.com>
 <rd82q9$2lc2$1@ciao.gmane.io>
Message-ID: <d0ff9195-92d1-3a19-069b-2fb814bd4118@wichmann.us>

On 6/27/20 12:23 PM, Jim wrote:
> On 6/27/20 1:10 PM, boB Stepp wrote:
>> On Sat, Jun 27, 2020 at 1:02 PM Jim <jf_byrnes at comcast.net> wrote:
>>> ... Years ago I had a problem with Firefox
>>> crashing when trying to reopen tabs and since then I have always turned
>>> that setting off.
>>
>> Perhaps this has been improved in current versions of Firefox?? I have
>> yet to experience this issue since I have switched to Firefox about
>> two or three years ago.? My tabs have always been seamlessly restored
>> for multiple instances of Firefox windows open.
>>
>>
> 
> That's probably true but I guess old habits die hard.
> 
> Regards,? Jim

Firefox still forgets its brain sometimes.

I use an extension Tab Session Manager which seems to solve that
problem.  The issue with that problem being solved is I accumulate too
many tabs... 500-600 open on my main Linux box is not at all uncommon.
Tab Session Manager writes out a json file with the tabs periodically,
plus on events (like browser close), and I've found it very reliable.


From mats at wichmann.us  Sat Jun 27 14:35:45 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 27 Jun 2020 12:35:45 -0600
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd83a3$3kuq$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
Message-ID: <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>

On 6/27/20 12:31 PM, Jim wrote:

>> I would look at writing a Firefox extension to do the cookie cleanup (if
>> there isn't one already that does a close enough job) rather than
>> something outside of Firefox.
> 
> I know I don't have the expertise to do that. Having to manually delete
> some cookies is not a big deal, I just enjoy programing with Python so I
> look for things I can automate.

There's something called SpeedyFox - it's not a plugin - which knows how
to clean up/compact sqlite databases for many browsers (and
Thunderbird), but I'm not aware that it operates on the cookie database.
 And it does ask that you shut down the browser before cleaning...



From jf_byrnes at comcast.net  Sat Jun 27 14:46:51 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 13:46:51 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <d0ff9195-92d1-3a19-069b-2fb814bd4118@wichmann.us>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <CANDiX9KEae0hw+WKQAhQCJpkk_RndLNhUdYcnsfO1_EYcTR7mg@mail.gmail.com>
 <rd82q9$2lc2$1@ciao.gmane.io>
 <d0ff9195-92d1-3a19-069b-2fb814bd4118@wichmann.us>
Message-ID: <rd846r$1jhl$1@ciao.gmane.io>

On 6/27/20 1:33 PM, Mats Wichmann wrote:
> On 6/27/20 12:23 PM, Jim wrote:
>> On 6/27/20 1:10 PM, boB Stepp wrote:
>>> On Sat, Jun 27, 2020 at 1:02 PM Jim <jf_byrnes at comcast.net> wrote:
>>>> ... Years ago I had a problem with Firefox
>>>> crashing when trying to reopen tabs and since then I have always turned
>>>> that setting off.
>>>
>>> Perhaps this has been improved in current versions of Firefox?? I have
>>> yet to experience this issue since I have switched to Firefox about
>>> two or three years ago.? My tabs have always been seamlessly restored
>>> for multiple instances of Firefox windows open.
>>>
>>>
>>
>> That's probably true but I guess old habits die hard.
>>
>> Regards,? Jim
> 
> Firefox still forgets its brain sometimes.
> 
> I use an extension Tab Session Manager which seems to solve that
> problem.  The issue with that problem being solved is I accumulate too
> many tabs... 500-600 open on my main Linux box is not at all uncommon.
> Tab Session Manager writes out a json file with the tabs periodically,
> plus on events (like browser close), and I've found it very reliable.
> 

Wow, I can't imagine having that many open, I don't even have that many 
bookmarks. At most I have 8 or 10 open and that's when I am researching 
something. When I am done I close them.

I guess I need to ask, why do you have that many open and how do you 
even know what is open?

Regards,  Jim




From jf_byrnes at comcast.net  Sat Jun 27 15:02:37 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 14:02:37 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
 <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
Message-ID: <rd854e$3ghp$1@ciao.gmane.io>

On 6/27/20 1:35 PM, Mats Wichmann wrote:
> On 6/27/20 12:31 PM, Jim wrote:
> 
>>> I would look at writing a Firefox extension to do the cookie cleanup (if
>>> there isn't one already that does a close enough job) rather than
>>> something outside of Firefox.
>>
>> I know I don't have the expertise to do that. Having to manually delete
>> some cookies is not a big deal, I just enjoy programing with Python so I
>> look for things I can automate.
> 
> There's something called SpeedyFox - it's not a plugin - which knows how
> to clean up/compact sqlite databases for many browsers (and
> Thunderbird), but I'm not aware that it operates on the cookie database.
>   And it does ask that you shut down the browser before cleaning...
> 

When I get a chance I'll try shutting down just the normal one and see 
if that helps.

Regards,  Jim


From alan.gauld at yahoo.co.uk  Sat Jun 27 18:41:48 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 27 Jun 2020 23:41:48 +0100
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd854e$3ghp$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
 <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
 <rd854e$3ghp$1@ciao.gmane.io>
Message-ID: <rd8hvc$2nik$1@ciao.gmane.io>

On 27/06/2020 20:02, Jim wrote:

> When I get a chance I'll try shutting down just the normal one and see 
> if that helps.

I'll be surprised. All instances of firefox will use the same
cookie database. If it gets deleted they will just regenerate
it using the in-memory cache. They are using sqlite as a
persistence mechanism not a database. Its table structures
are used just as a useful data format and to provide basic
multi-session access/locking control.

But so long as there is a single instance running you probably
can't even guarantee that changes made by the other instances
(let alone any external program) will stick.

-- 
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 Jun 27 19:05:39 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 28 Jun 2020 09:05:39 +1000
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
Message-ID: <20200627230539.GA56218@cskk.homeip.net>

On 26Jun2020 11:21, John Weller <john at johnweller.co.uk> wrote:
>I have a Python program which will be running 24/7 (I hope ?).  It is 
>generating data in a file which I want to clean up overnight.  The way 
>I am looking at doing it is to run a separate program as a Cron job at 
>midnight ? will that work?  The alternative is to add it to the loop 
>and check for the time. I have tried researching this but only got even 
>more confused.

Running a separate program is perfectly reasonable.

And crontab is a perfect place for a regular task like this.

The primary issue usually is that you do not want both programms to be 
using the file at the same time.

Supposing the file were, say, a CSV file to which your long running 
programme (A) appended data. ANd that the clean up program (B) reads the 
CSV file, tidies some stuff, and rewrites the CSV file. You can imagine 
this sequence:

    - programme B opens the file and reads the data
    - programme B thinks about the data to clean it
    - programme A appends more data to the file
    - programme B rewrites the clean data into the file,
      _overwriting_ the new data programme A just appended

The usual process with a shared external file is to use a lock facility.  
These come in a few forms, and it is essential that both programme A and 
programme B use the same locking system.

One of the easiest and most portable is to make a lock file while you 
work with the file. If your data file is called "foo" you might use a 
lock fie called "foo.lock".

On a UNIX type system (includes Linux) you can atomicly make such a file 
like this:

    import os
    .......
    lockpath = datafilepath + '.lock'
    lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0)

That is a special mode of the OS "open" call (_not_ Python's default 
"open" builtin) whose parameters have the following meanings:

    - os.O_CREAT: create the file if missing
    - os.O_EXCL: ensure that the file is created - if it already exists 
      this raises an exception
    - os.O_RDWR: open the file for read and write
    - 0: the initial permissions, ensuring that the file is _not_ 
      readable or writable

See "man 2 open" on a UNIX system for the spec.

The combination of O_RDWR and 0 permissions means that if the file 
already exists (made by the "other" programme) then it won't have any 
permissions, which means we won't get read or write access and the open 
will fail. The nice thing about this is that the initial permissions are 
_immediate_ when the file is created by the OS - there's no tiny window 
where the file has read/write perms which then get removed - the OS 
ensures it. This is nice on networked file shares (if they are 
reliable).

Anyway, the upshort of the os.open() call above is that if the lockfile 
already exists, the open will fail, and otherwise it will succeed, 
preventing antoehr programme doing the same thing.

When finished, close the lockfd and remove the lock file:

    os.close(lockfd)
    os.remove(lockpath)

No, because the whole scenario is that occasionally both programms want 
the file at the same time, the os.open _will_ fail in that case. SO the 
idea is that you repeat it until it succeeds, then do your work:

    while True:
        try:
            lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0)
        except OSError as e:
            print("lock not obtained, sleeping")
            time.sleep(1)
        else:
            break
    .... work with the data file ...
    os.close(lockfd)
    os.remove(lockpath)

Put that logic in both programmes and you should be ok.

You can see a more elaborate version of this logic in my "makelockfile" 
function here:

    https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/fileutils.py#lines-527

(Atlassian are going to nuke that repo soon, alas, because they find 
mercurial too hard. But until then the link should be good.)

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

From PyTutor at DancesWithMice.info  Sat Jun 27 19:26:02 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Sun, 28 Jun 2020 11:26:02 +1200
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd8hvc$2nik$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
 <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
 <rd854e$3ghp$1@ciao.gmane.io> <rd8hvc$2nik$1@ciao.gmane.io>
Message-ID: <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info>

On 28/06/20 10:41 AM, Alan Gauld via Tutor wrote:
> On 27/06/2020 20:02, Jim wrote:
>> When I get a chance I'll try shutting down just the normal one and see
>> if that helps.
> 
> I'll be surprised. All instances of firefox will use the same
> cookie database. If it gets deleted they will just regenerate
> it using the in-memory cache. They are using sqlite as a
> persistence mechanism not a database. Its table structures
> are used just as a useful data format and to provide basic
> multi-session access/locking control.
> 
> But so long as there is a single instance running you probably
> can't even guarantee that changes made by the other instances
> (let alone any external program) will stick.


+1 "Persistence", except that there is a periodic (by config-setting) 
update/backup.

Exactly! The live system is not continually/regularly re-reading the 
'database' because it already (thinks it) 'knows' what's going-on.

The problem is ultimately one of 'ownership'. If it is 'my' data, I will 
decide the who/what/why of access, etc!

FF does *not* expect (or want?) to share these records with anyone or 
anything else. Accordingly, they have not been designed for multi-access 
(per a regular RDBMS). Yes, if the relevant FF instance (see below) has 
been closed-down, and the files are altered, this idea may succeed, but 
once-again, that would be doing something most likely to be outside of 
any FF design considerations - here be dragons!


(further to previous-post, above)
There *may* be different 'databases' - because FF works from a "profile" 
and can be made to configure itself from multiple profiles on the single 
machine/OpSys - thus in the days when PCs were often shared, different 
students could use the same machine but keep their data separate, 'his' 
and 'hers' at home, and so-on. Largely unused by most, but still 
available/possible.

Finally, (yes, am showing-off here) the Firefox [Web] Developer Edition 
(and quite possibly other 'special versions' of FF) install separately 
and outside the usual system-wide context - (stated to be) primarily to 
maintain separate settings, profiles, etc. So, the multiple versions of 
Firefox not only have separate profiles but also keep them in a 
different (default) location.
(Firefox can be instructed where to keep its profiles, should one not 
wish to accept their default/recommendation)


Back to the OP:
I salute your brave efforts, and your intent to use Python. However, the 
issues are more to do with FF than Python. Thus, you may find more help 
and advice from MDN (the Mozilla Developers' Network).

There is an Add-on/Extension called Cookie-Editor which will list the 
cookies relevant to the active tab/web-page, and gives one the 
opportunity to delete them (and more). This is considerably more 
accessible (and flexible - and revealing!) than using the Preferences | 
Privacy and Security facility! I use it for controlling and debugging 
the cookie side of web-dev 'all the time'...

At the sledge-hammer end of the tool-rack, it is possible to set Firefox 
to wipe all cookies at the end of each session. This will definitely 
counter any sneaky marketing efforts and 'tracking', but may also have 
the effect of undoing the 'remember me' type of facility on sites where 
you may wish to maintain a 'membership'...
-- 
Regards =dn

From mats at wichmann.us  Sat Jun 27 21:27:43 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sat, 27 Jun 2020 19:27:43 -0600
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
Message-ID: <DEE837F3-2B88-421B-AD6C-5F69DB314214@wichmann.us>

On June 26, 2020 4:21:02 AM MDT, John Weller <john at johnweller.co.uk> wrote:
>I have a Python program which will be running 24/7 (I hope ?).  It is
>generating data in a file which I want to clean up overnight.  The way
>I am looking at doing it is to run a separate program as a Cron job at
>midnight ? will that work?  The alternative is to add it to the loop
>and check for the time. I have tried researching this but only got even
>more confused.
>
> 
>
>Thanks
>
> 
>
>John
>
> 
>
>John Weller
>
>01380 723235
>
>07976 393631
>
> 
>
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor

a common technique is a "log rotate" one... I see it's got a wikipedia page, take a look for some ideas.
-- 
Sent from a mobile device with K-9 Mail. Please excuse my brevity.

From jf_byrnes at comcast.net  Sat Jun 27 22:18:19 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 21:18:19 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <rd8hvc$2nik$1@ciao.gmane.io>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
 <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
 <rd854e$3ghp$1@ciao.gmane.io> <rd8hvc$2nik$1@ciao.gmane.io>
Message-ID: <rd8ulb$ibm$1@ciao.gmane.io>

On 6/27/20 5:41 PM, Alan Gauld via Tutor wrote:
> On 27/06/2020 20:02, Jim wrote:
> 
>> When I get a chance I'll try shutting down just the normal one and see
>> if that helps.
> 
> I'll be surprised. All instances of firefox will use the same
> cookie database. If it gets deleted they will just regenerate
> it using the in-memory cache. They are using sqlite as a
> persistence mechanism not a database. Its table structures
> are used just as a useful data format and to provide basic
> multi-session access/locking control.
> 
> But so long as there is a single instance running you probably
> can't even guarantee that changes made by the other instances
> (let alone any external program) will stick.
> 

You're probably right. Just thinking, with no real basis to do so, that 
private mode does not retain cookies so maybe there is no reason for it 
to use cookies.sqlite-wal.

Anyway I've come this far, the script is written and works until Firefox 
does it's thing, so I might as well try one last time.

Thanks,  Jim


From jf_byrnes at comcast.net  Sat Jun 27 22:30:04 2020
From: jf_byrnes at comcast.net (Jim)
Date: Sat, 27 Jun 2020 21:30:04 -0500
Subject: [Tutor] Advice on working with Firefox's cookies.sqlite
In-Reply-To: <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info>
References: <rd7t0r$2ccf$1@ciao.gmane.io> <rd7u4k$or8$1@ciao.gmane.io>
 <rd81k6$4t9$1@ciao.gmane.io>
 <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org>
 <rd83a3$3kuq$1@ciao.gmane.io>
 <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us>
 <rd854e$3ghp$1@ciao.gmane.io> <rd8hvc$2nik$1@ciao.gmane.io>
 <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info>
Message-ID: <rd8vbc$1tpu$1@ciao.gmane.io>

On 6/27/20 6:26 PM, dn via Tutor wrote:
> On 28/06/20 10:41 AM, Alan Gauld via Tutor wrote:
>> On 27/06/2020 20:02, Jim wrote:
>>> When I get a chance I'll try shutting down just the normal one and see
>>> if that helps.
>>
>> I'll be surprised. All instances of firefox will use the same
>> cookie database. If it gets deleted they will just regenerate
>> it using the in-memory cache. They are using sqlite as a
>> persistence mechanism not a database. Its table structures
>> are used just as a useful data format and to provide basic
>> multi-session access/locking control.
>>
>> But so long as there is a single instance running you probably
>> can't even guarantee that changes made by the other instances
>> (let alone any external program) will stick.
> 
> 
> +1 "Persistence", except that there is a periodic (by config-setting) 
> update/backup.
> 
> Exactly! The live system is not continually/regularly re-reading the 
> 'database' because it already (thinks it) 'knows' what's going-on.
> 
> The problem is ultimately one of 'ownership'. If it is 'my' data, I will 
> decide the who/what/why of access, etc!
> 
> FF does *not* expect (or want?) to share these records with anyone or 
> anything else. Accordingly, they have not been designed for multi-access 
> (per a regular RDBMS). Yes, if the relevant FF instance (see below) has 
> been closed-down, and the files are altered, this idea may succeed, but 
> once-again, that would be doing something most likely to be outside of 
> any FF design considerations - here be dragons!
> 
> 
> (further to previous-post, above)
> There *may* be different 'databases' - because FF works from a "profile" 
> and can be made to configure itself from multiple profiles on the single 
> machine/OpSys - thus in the days when PCs were often shared, different 
> students could use the same machine but keep their data separate, 'his' 
> and 'hers' at home, and so-on. Largely unused by most, but still 
> available/possible.
> 
> Finally, (yes, am showing-off here) the Firefox [Web] Developer Edition 
> (and quite possibly other 'special versions' of FF) install separately 
> and outside the usual system-wide context - (stated to be) primarily to 
> maintain separate settings, profiles, etc. So, the multiple versions of 
> Firefox not only have separate profiles but also keep them in a 
> different (default) location.
> (Firefox can be instructed where to keep its profiles, should one not 
> wish to accept their default/recommendation)
> 
> 
> Back to the OP:
> I salute your brave efforts, and your intent to use Python. However, the 
> issues are more to do with FF than Python. Thus, you may find more help 
> and advice from MDN (the Mozilla Developers' Network).

That's thought, thanks.

> There is an Add-on/Extension called Cookie-Editor which will list the 
> cookies relevant to the active tab/web-page, and gives one the 
> opportunity to delete them (and more). This is considerably more 
> accessible (and flexible - and revealing!) than using the Preferences | 
> Privacy and Security facility! I use it for controlling and debugging 
> the cookie side of web-dev 'all the time'...
> 
> At the sledge-hammer end of the tool-rack, it is possible to set Firefox 
> to wipe all cookies at the end of each session. This will definitely 
> counter any sneaky marketing efforts and 'tracking', but may also have 
> the effect of undoing the 'remember me' type of facility on sites where 
> you may wish to maintain a 'membership'...

I won't pick up the sledge-hammer. My aim is to keep the cookies that 
benefit me and get rid of the ones that don't. Its not that time 
consuming to manually delete the unwanted cookies at the end of the day. 
I just thought it would be an interesting python project.

Regards,  Jim


From PyTutor at DancesWithMice.info  Sun Jun 28 02:21:08 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Sun, 28 Jun 2020 18:21:08 +1200
Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2'
In-Reply-To: <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com>
References: <DE073801-E363-4ECB-89C2-03A5903076F7@gmail.com>
 <eb66bb91-1e96-8528-ebaf-da360c9db76b@wichmann.us>
 <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us>
 <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com>
 <d4fbe4e0-3ef2-c047-c66b-16afb7661661@DancesWithMice.info>
 <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com>
Message-ID: <aee971e2-6748-3771-fc32-a92fefa9a79f@DancesWithMice.info>

On 27/06/20 1:44 PM, Cravan wrote:
> ?> On 27/6/20, 8:13 AM, "Tutor on behalf of dn via Tutor" <tutor-bounces+savageapple850=gmail.com at python.org on behalf of tutor at python.org> wrote:
> 
>    	
>      > It may be worth taking a step-back - both in terms of the design you are
>      implementing and the questions you are asking of us:-
> Sure! I apologise for any inconvenience caused, and really appreciate your efforts to help me

It's not inconvenience, per-se, more a thought that sometimes 'the 
problem' may not be a 'programming error', but instead be a short-coming 
in design...
(I don't know! However, you will see more of that level of question, below)


>      > Have looked and looked, and then used 'find', but failed to find the
>      code-line at-error. Why? [help us to help you!]
> Essentially right now my dictionary is only churning out values of a current index when printing it out, so e.g.
> {((1023, 767), 'U'): 0, ((1023, 767), 'D'): 0, ((1023, 767), 'L'): 0, ((1023, 767), 'R'): 0} when it's supposed to be inclusive of all the coords. in the game (and the possible actions). I can't seem to rectify it(I don't know how).

So, you didn't include this information!? The more generous you can be 
with us, the more readily folk will dive-in to help you. You will see 
(below) that one problem may be purely Python, thus even those who do 
not use Pygame could have been helping, given the info...


Please see previous msg - covering the generation of different views of 
the same data/data-components.

Why look at all possible coordinates, cf only those occupied by players, 
zombies, and obstructions? (see later)

Regardless, to be able to see what's (not) happening, insert a 
debug-print after self.stateSpace = [(a,b)] (and the nested for-loops), 
run, and observe...

What is the content of self.stateSpace, its type(), and its len()?

If that is not sufficient to provoke an 'ahah!', then put another 
debug-print 'inside' the loops...

My guess is that you have confused the syntax for a list comprehension 
with that appropriate to explicit, nested, for-loops. To add elements to 
the end of a list, use list.append( value ) - see Python Docs for more info.

Another [design] question, if I may: might it be better to use a 
dict[ionary] so that (later) you could have either "serial" or 
"direct-access" to 'squares' (coordinates) in the game's grid?


>      > Aside from learning Python's idioms, are you using a competent IDE?
>      Could you then use full-names instead of abbreviations, without adding
>      major effort? I think we could guess what a "zomb" is, but would it be
>      better (and kinder) to remove all doubt?
> I'm using Atom to do it.

IIRC once a variable-name has been entered, next time the entry being 
typed appears to be similar, Atom will offer to 'fill' for you - saving 
typing *and* improving readability...


  An enemy in this case would be a zombie.(zomb) who is seeking to kill 
the player. The player has a health bar which decreases when the zombie 
touches it, and my game is a maze game. The zombies can pass through 
walls to give them an advantage over the player (making it more difficult)

So, (one) "collision" is defined as a zombie either landing on the same 
'square' as the player, or on a neighboring square. Which, and 
(expressed in English) how do you see this as a calculation (and 
data-structure)?


>      >  Have comments and "docstrings" (a pythonic idiom) been used to describe
>      what the code/each function is supposed to do, and why?
> Well, some (haha).

Recognising that there is a difference between someone working 
by-and-for himself, and someone who is part of a team; by involving us 
have you effectively moved from one to the other? ie would improving 
this situation help us to understand your thinking and thus move more 
rapidly towards an 'answer'?


>      > If the game's environment is described as a "grid", why is its width and
>      height described using anything other than int[eger]s?
> Width and Height are the actual width and height. Essentially gridwidth and gridheight are the width and height (in tilesize units) e.g. 3 tiles x 4 tiles for example

Which strike me as integers!
(yet the code calls int() to convert them, but from what?)

Also, how many times does the code perform these conversions, cf the 
number of times that it is strictly-necessary?


>      > What is the purpose of "state"? Is there a difference between "state"
>      and "position" (or next-/previous-position)?
> A state is essentially the current state of the system (i.e. I can set the state as the product of my coordinates, for example but now I'm using it as the coords. for convenience), within a set of states (product of the maximum y-coord and the max. x-coord but it also can be all the coords in my environment(which I am using))

With apologies, but I failed to understand.

Is "state" related to whether the game is 'on' or over? Is it the 
ability of the player (or each zombie) to move into a neighboring 
square/tile? Something else? How would you express its purpose and 
functions, in English?

The "all the coords" part is (hopefully) addressed with the debug-print 
investigation proposed, above.


>      > Have you understood the (animation) concept of collision? (assuming that
>      is part of the intent here) Have you noted various algorithms and
>      approximations which are commonly-used?
> Yes, the collision part is fine since I was able to get it to work before the implementation of machine learning

-- 
Regards =dn

From john at johnweller.co.uk  Sun Jun 28 05:59:16 2020
From: john at johnweller.co.uk (John Weller)
Date: Sun, 28 Jun 2020 10:59:16 +0100
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <20200627230539.GA56218@cskk.homeip.net>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
 <20200627230539.GA56218@cskk.homeip.net>
Message-ID: <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk>

Thank you to all who responded.  I was conscious of the file locking issue and had a strategy in mind to cope.  My concern was if Python could manage.  I am an experienced programmer new to Python and had visions of the early interpreted languages I used such as those on the BBC Micro and early PCs  ?

Thanks again

John

John Weller
01380 723235
07976 393631

-----Original Message-----
From: Cameron Simpson <cs at cskk.id.au> 
Sent: 28 June 2020 00:06
To: John Weller <john at johnweller.co.uk>
Cc: 'Python Tutor' <tutor at python.org>
Subject: Re: [Tutor] Running Python Scripts at same time

On 26Jun2020 11:21, John Weller <john at johnweller.co.uk> wrote:
>I have a Python program which will be running 24/7 (I hope ?).  It is 
>generating data in a file which I want to clean up overnight.  The way 
>I am looking at doing it is to run a separate program as a Cron job at 
>midnight ? will that work?  The alternative is to add it to the loop 
>and check for the time. I have tried researching this but only got even 
>more confused.

Running a separate program is perfectly reasonable.

And crontab is a perfect place for a regular task like this.

The primary issue usually is that you do not want both programms to be using the file at the same time.

Supposing the file were, say, a CSV file to which your long running programme (A) appended data. ANd that the clean up program (B) reads the CSV file, tidies some stuff, and rewrites the CSV file. You can imagine this sequence:

    - programme B opens the file and reads the data
    - programme B thinks about the data to clean it
    - programme A appends more data to the file
    - programme B rewrites the clean data into the file,
      _overwriting_ the new data programme A just appended

The usual process with a shared external file is to use a lock facility.  
These come in a few forms, and it is essential that both programme A and programme B use the same locking system.

One of the easiest and most portable is to make a lock file while you work with the file. If your data file is called "foo" you might use a lock fie called "foo.lock".

On a UNIX type system (includes Linux) you can atomicly make such a file like this:

    import os
    .......
    lockpath = datafilepath + '.lock'
    lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0)

That is a special mode of the OS "open" call (_not_ Python's default "open" builtin) whose parameters have the following meanings:

    - os.O_CREAT: create the file if missing
    - os.O_EXCL: ensure that the file is created - if it already exists 
      this raises an exception
    - os.O_RDWR: open the file for read and write
    - 0: the initial permissions, ensuring that the file is _not_ 
      readable or writable

See "man 2 open" on a UNIX system for the spec.

The combination of O_RDWR and 0 permissions means that if the file already exists (made by the "other" programme) then it won't have any permissions, which means we won't get read or write access and the open will fail. The nice thing about this is that the initial permissions are _immediate_ when the file is created by the OS - there's no tiny window where the file has read/write perms which then get removed - the OS ensures it. This is nice on networked file shares (if they are reliable).

Anyway, the upshort of the os.open() call above is that if the lockfile already exists, the open will fail, and otherwise it will succeed, preventing antoehr programme doing the same thing.

When finished, close the lockfd and remove the lock file:

    os.close(lockfd)
    os.remove(lockpath)

No, because the whole scenario is that occasionally both programms want the file at the same time, the os.open _will_ fail in that case. SO the idea is that you repeat it until it succeeds, then do your work:

    while True:
        try:
            lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0)
        except OSError as e:
            print("lock not obtained, sleeping")
            time.sleep(1)
        else:
            break
    .... work with the data file ...
    os.close(lockfd)
    os.remove(lockpath)

Put that logic in both programmes and you should be ok.

You can see a more elaborate version of this logic in my "makelockfile" 
function here:

    https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/fileutils.py#lines-527

(Atlassian are going to nuke that repo soon, alas, because they find mercurial too hard. But until then the link should be good.)

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


From alan.gauld at yahoo.co.uk  Sun Jun 28 11:35:49 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 28 Jun 2020 16:35:49 +0100
Subject: [Tutor] Running Python Scripts at same time
In-Reply-To: <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk>
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
 <20200627230539.GA56218@cskk.homeip.net>
 <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk>
Message-ID: <rdadcl$2fbg$1@ciao.gmane.io>

On 28/06/2020 10:59, John Weller wrote:
> I am an experienced programmer new to Python and had visions 
> of the early interpreted languages I used such as those of> the BBC Micro and early PCs

While there is a shared heritage as interpreted languages
Python is part of the new breed and is far more capable than
those earlier BASIC languages. It is also designed to integrate
with compiled libraries from the ground up and so has
accumulated a vast library that can tackle most jobs
for which the highest speed is not the chief criterion.

In many ways Python's structured syntax and compile-to-bytecode
approach is more like UCSD Pascal that used to be available
for the Beeb than it is to BBC BASIC.

-- 
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 Jun 28 11:42:13 2020
From: __peter__ at web.de (Peter Otten)
Date: Sun, 28 Jun 2020 17:42:13 +0200
Subject: [Tutor] Running Python Scripts at same time
References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk>
 <DEE837F3-2B88-421B-AD6C-5F69DB314214@wichmann.us>
Message-ID: <rdadom$39ec$1@ciao.gmane.io>

Mats Wichmann wrote:

> On June 26, 2020 4:21:02 AM MDT, John Weller <john at johnweller.co.uk>
> wrote:
>>I have a Python program which will be running 24/7 (I hope ?).  It is
>>generating data in a file which I want to clean up overnight.  The way
>>I am looking at doing it is to run a separate program as a Cron job at
>>midnight ? will that work?  The alternative is to add it to the loop
>>and check for the time. I have tried researching this but only got even
>>more confused.

> a common technique is a "log rotate" one... I see it's got a wikipedia
> page, take a look for some ideas.

You may also consider Python's logging library which supports log rotation:

https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler

That way you don't need the cronjob, or, if you want to do some 
postprocessing, can point it to the latest backup. Locking will become a 
non-issue.


From l2verma at uwaterloo.ca  Sun Jun 28 19:18:54 2020
From: l2verma at uwaterloo.ca (Lakshay Verma)
Date: Sun, 28 Jun 2020 23:18:54 +0000
Subject: [Tutor] Subplotting Figure Handles - Python Help
Message-ID: <YT1PR01MB37403FA664B6E5FEE9F6760589910@YT1PR01MB3740.CANPRD01.PROD.OUTLOOK.COM>

Hello,

I am currently working on a project whereby I collect data from a redshift database and do some analysis on it. I have made several functions that all generate figures, and output them as figure handles. For example, a function will take in query text, run the query in the database, and then I'll use pandas to store the data in a dataframe, and matplotlib to graph the data and do some statistical analysis on it. The function will then return a figure handle ( <Figure size 432x288> ). How do I go about subplotting these figures? Because right now, I am not able to subplot them and it's really frustrating because when I save the figures to a pdf, I'm getting 20+ page pdfs whereas I would like 5 pages whereby I can group plots that analyze similar data. I'd be happy to discuss this over a video call so you can see the code and get a better idea. Thanks!
Regards,

Lakshay Verma
Chemical Engineering Student
University of Waterloo
E: l2verma at edu.uwaterloo.ca<mailto:l2verma at edu.uwaterloo.ca>
P: (647) 721-8414


From manpritsinghece at gmail.com  Mon Jun 29 08:35:01 2020
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Mon, 29 Jun 2020 18:05:01 +0530
Subject: [Tutor] key parameter in sorted
Message-ID: <CAO1OCwYQuUj_xBO6P+vZg3Bf7J0_DH2f=6FaK6K6QB92QCL79g@mail.gmail.com>

Sir,
According to the python documentation,function sorted
<https://docs.python.org/3/library/functions.html#sorted> have a *key*
parameter to specify a function to be called on each  element prior to
making comparisons.

consider a case if i am using python 3.6, and i have to remove duplicates
from a list, while maintaining the order of the elements, i just need to
know if my solution(which is given below )  is syntactically correct and
efficient or not .
The result i am getting is correct and have tested it  so many times .
Reason for asking this question is, here i have passed  method of list
data type (list.index) to the key parameter of sorted function . Can i pass
a method to the key parameter of sorted function ?

lx = [2, 5, 4, 6, 4, 2, 3, 6]
sorted(set(lx), key=lx.index)

Regards
Manprit Singh

From __peter__ at web.de  Mon Jun 29 09:46:24 2020
From: __peter__ at web.de (Peter Otten)
Date: Mon, 29 Jun 2020 15:46:24 +0200
Subject: [Tutor] key parameter in sorted
References: <CAO1OCwYQuUj_xBO6P+vZg3Bf7J0_DH2f=6FaK6K6QB92QCL79g@mail.gmail.com>
Message-ID: <rdcrbh$2bdr$1@ciao.gmane.io>

Manprit Singh wrote:

> Sir,
> According to the python documentation,function sorted
> <https://docs.python.org/3/library/functions.html#sorted> have a *key*
> parameter to specify a function to be called on each  element prior to
> making comparisons.
> 
> consider a case if i am using python 3.6, and i have to remove duplicates
> from a list, while maintaining the order of the elements, i just need to
> know if my solution(which is given below )  is syntactically correct and
> efficient or not .
> The result i am getting is correct and have tested it  so many times .
> Reason for asking this question is, here i have passed  method of list
> data type (list.index) to the key parameter of sorted function . Can i
> pass a method to the key parameter of sorted function ?

You can pass any callable object as the key parameter.

> lx = [2, 5, 4, 6, 4, 2, 3, 6]
> sorted(set(lx), key=lx.index)

Your code is correct, but not efficient: you need up to len(lx) linear 
searches over the list just to calculate the key values.

An alternative may be to rely on dicts preserving insertion order 
(officially in 3.7, but implemented in 3.6):

>>> lx = [2, 5, 4, 6, 4, 2, 3, 6]
>>> list(dict.fromkeys(lx))
[2, 5, 4, 6, 3]



From __peter__ at web.de  Mon Jun 29 09:51:46 2020
From: __peter__ at web.de (Peter Otten)
Date: Mon, 29 Jun 2020 15:51:46 +0200
Subject: [Tutor] key parameter in sorted
References: <CAO1OCwYQuUj_xBO6P+vZg3Bf7J0_DH2f=6FaK6K6QB92QCL79g@mail.gmail.com>
 <rdcrbh$2bdr$1@ciao.gmane.io>
Message-ID: <rdcrli$2bdr$2@ciao.gmane.io>

Peter Otten wrote:

> Manprit Singh wrote:

>> lx = [2, 5, 4, 6, 4, 2, 3, 6]
>> sorted(set(lx), key=lx.index)

Another option:

>>> def unique(items):
...     seen = set()
...     for item in items:
...         if item not in seen:
...             yield item
...             seen.add(item)
... 
>>> list(unique(lx))
[2, 5, 4, 6, 3]



From david at lowryduda.com  Mon Jun 29 10:24:18 2020
From: david at lowryduda.com (David Lowry-Duda)
Date: Mon, 29 Jun 2020 10:24:18 -0400
Subject: [Tutor] Subplotting Figure Handles - Python Help
In-Reply-To: <YT1PR01MB37403FA664B6E5FEE9F6760589910@YT1PR01MB3740.CANPRD01.PROD.OUTLOOK.COM>
References: <YT1PR01MB37403FA664B6E5FEE9F6760589910@YT1PR01MB3740.CANPRD01.PROD.OUTLOOK.COM>
Message-ID: <20200629142418.GA21362@icerm-dld>

Hello!

On Sun, Jun 28, 2020 at 11:18:54PM +0000, Lakshay Verma wrote:
> Hello,
> 
> How do I go about subplotting these figures? Because right now, I am 
> not able to subplot them and it's really frustrating because when I 
> save the figures to a pdf, I'm getting 20+ page pdfs whereas I would 
> like 5 pages whereby I can group plots that analyze similar data.

Without seeing your code, it's hard to give specific pointers. But I 
suspect you'll get far if you adjust the code in some of the matplotlib 
examples on the matplotlib site. In particular, I think this page

https://matplotlib.org/gallery/subplots_axes_and_figures/subplots_demo.html#sphx-glr-gallery-subplots-axes-and-figures-subplots-demo-py

will be of interest. A similar, but condensed, presentation is on 
StackOverflow at

https://stackoverflow.com/questions/31726643/how-do-i-get-multiple-subplots-in-matplotlib

> I'd be happy to discuss this over a video call so you can see the code 
> and get a better idea. Thanks!

This isn't something I'd be interested in. But I think if you distilled 
your question to a form where you could share the code on this list, it 
would raise the likelood both of getting any answer and an explicitly 
helpful answer.

Finally, in case you have other matplotlib-specific questions in the 
future, it may be helpful to post on the matplotlib-users mailing list

https://mail.python.org/mailman/listinfo/matplotlib-users

Good luck!

- DLD

-- 
David Lowry-Duda <david at lowryduda.com> <davidlowryduda.com>

From adameyring at gmail.com  Mon Jun 29 10:44:26 2020
From: adameyring at gmail.com (Adam Eyring)
Date: Mon, 29 Jun 2020 10:44:26 -0400
Subject: [Tutor] Subplotting Figure Handles - Python Help
In-Reply-To: <YT1PR01MB37403FA664B6E5FEE9F6760589910@YT1PR01MB3740.CANPRD01.PROD.OUTLOOK.COM>
References: <YT1PR01MB37403FA664B6E5FEE9F6760589910@YT1PR01MB3740.CANPRD01.PROD.OUTLOOK.COM>
Message-ID: <CAPStRW8uvMa3VOz3aYwPe1DC_Cyj_5pfRgBmHCYcSK1_K63wOA@mail.gmail.com>

I'm not sure if this would help you, but you may want to check out the
Bokeh package to see if it offers the plotting options you need if you get
stuck on matplotlib. I like the way it does subplots.
https://bokeh.org/

AME

On Mon, Jun 29, 2020 at 9:25 AM Lakshay Verma <l2verma at uwaterloo.ca> wrote:

> Hello,
>
> I am currently working on a project whereby I collect data from a redshift
> database and do some analysis on it. I have made several functions that all
> generate figures, and output them as figure handles. For example, a
> function will take in query text, run the query in the database, and then
> I'll use pandas to store the data in a dataframe, and matplotlib to graph
> the data and do some statistical analysis on it. The function will then
> return a figure handle ( <Figure size 432x288> ). How do I go about
> subplotting these figures? Because right now, I am not able to subplot them
> and it's really frustrating because when I save the figures to a pdf, I'm
> getting 20+ page pdfs whereas I would like 5 pages whereby I can group
> plots that analyze similar data. I'd be happy to discuss this over a video
> call so you can see the code and get a better idea. Thanks!
> Regards,
>
> Lakshay Verma
> Chemical Engineering Student
> University of Waterloo
> E: l2verma at edu.uwaterloo.ca<mailto:l2verma at edu.uwaterloo.ca>
> P: (647) 721-8414
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>