From diana.katz at gmail.com  Fri Jan  1 20:26:33 2021
From: diana.katz at gmail.com (Diana Katz)
Date: Fri, 1 Jan 2021 20:26:33 -0500
Subject: [Tutor] Code
Message-ID: <D4D959FE-1A88-4C0C-AAEC-BAFEF033F6CF@gmail.com>

Im trying to figure out a fast way to see how many sellers on poshmark cross post somewhere else- like ebay or instagram closet?
Would python be the right way to go about scraping this data to figure out the answer? Would it be very difficult?

Sent from my iPhone

From marc.tompkins at gmail.com  Fri Jan  1 20:49:02 2021
From: marc.tompkins at gmail.com (Marc Tompkins)
Date: Fri, 1 Jan 2021 17:49:02 -0800
Subject: [Tutor] Code
In-Reply-To: <D4D959FE-1A88-4C0C-AAEC-BAFEF033F6CF@gmail.com>
References: <D4D959FE-1A88-4C0C-AAEC-BAFEF033F6CF@gmail.com>
Message-ID: <CAKK8jXZ06y_mPqXLaPyYE_A7AxBbyD9G6JW4MBEEKnrZgufGNA@mail.gmail.com>

If scraping is what you need to do, Python offers some of the most
efficient ways to do it - but if it's at all possible, I strongly suggest
that you consider using APIs for the sites you want to look at (Python +
the requests library would be my choice for doing that, too.)  Scraping
sites without permission is ethically grey, but quite apart from that it
can get you banned. Playing nice is best for everybody.

On Fri, Jan 1, 2021 at 5:27 PM Diana Katz <diana.katz at gmail.com> wrote:

> Im trying to figure out a fast way to see how many sellers on poshmark
> cross post somewhere else- like ebay or instagram closet?
> Would python be the right way to go about scraping this data to figure out
> the answer? Would it be very difficult?
>
> Sent from my iPhone
> _______________________________________________
> 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  Sat Jan  2 11:27:28 2021
From: john at johnweller.co.uk (John Weller)
Date: Sat, 2 Jan 2021 16:27:28 -0000
Subject: [Tutor] Ftplib Error
Message-ID: <001e01d6e124$2a7dfb60$7f79f220$@johnweller.co.uk>

I use the following code to download a list of files from a web server:

 

    try:

        ftp = ftplib.FTP(data.ftp_host)  # connect to host, default port

        ftp.login(user=data.ftp_user <ftp://ftp.login(user=data.ftp_user> , passwd=data.ftp_passwd)

    except ftplib.all_errors as err:

        # Log the error

        logging.error(err)

    else:

        ftp.cwd(data.ftp_dir) <ftp://ftp.cwd(data.ftp_dir)> 

        files = ftp.nlst() <ftp://ftp.nlst()> 

 

I am using VS Code and have just installed Pylance.  It is now telling me that ?all_errors? is not a valid exception class but the documentation suggests that it is unless I am mis-reading the documentation (always a possibility ?).  Your advice will be gratefully received.

 

John

 

John Weller

07976 393631

 


From 3007645 at students.ankenyschools.org  Mon Jan  4 10:38:27 2021
From: 3007645 at students.ankenyschools.org (Weston Batey)
Date: Mon, 4 Jan 2021 09:38:27 -0600
Subject: [Tutor] Help!
Message-ID: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>

My school is currently using edhesive to do python work and I need help
answering this question. I am in 8.6 arrays as parameters. A ___________ is
a variable used to pass information to a method.

From pytutor at danceswithmice.info  Mon Jan  4 14:07:37 2021
From: pytutor at danceswithmice.info (dn)
Date: Tue, 5 Jan 2021 08:07:37 +1300
Subject: [Tutor] Help!
In-Reply-To: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>
References: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>
Message-ID: <bb0ab18e-db1f-c90c-dbc8-28a4cd59f1d8@DancesWithMice.info>

On 1/5/21 4:38 AM, Weston Batey wrote:
> My school is currently using edhesive to do python work and I need help
> answering this question. I am in 8.6 arrays as parameters. A ___________ is
> a variable used to pass information to a method.


Welcome to the list.

We're not in the business of doing assignments for you. We will help you
to (learn how to) do-stuff with Python.


Recommend you review the material just-covered in the course. Surely the
topic is covered there?


To amplify your learning, consider accessing other tutorial sites and/or
books to be able to cross-reference between that/them and your course
materials - when you don't understand one, the other will help-hopefully.


What is a method?
What do we call/term a 'method' that is not part of a class?
If we have a simple method which doubles or triples its input (say), how
do we input/pass that input-information into the method?

Hint: be aware that two words appear to be used for the same thing - but
there is a difference when one considers what is happening when
*defining* a method, compared with when that method is *call*ed!

Also please note: there is no such thing as an "array" in Python. Python
offers "collections" - in various forms.


Web.Refs:
The Python Tutorial https://docs.python.org/3/tutorial/index.html
(specifically 4.6. Defining Functions)

Arguments and Parameters
https://python.tecladocode.com/4_treasure_hunters/4_arguments_and_parameters.html#what-is-an-argument

Python Function Arguments ? Learn the 3 types of Arguments
https://techvidvan.com/tutorials/python-function-arguments/
-- 
Regards =dn

From cs at cskk.id.au  Mon Jan  4 16:18:33 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 5 Jan 2021 08:18:33 +1100
Subject: [Tutor] Help!
In-Reply-To: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>
References: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>
Message-ID: <X/OGKdx2X8z+ma2+@cskk.homeip.net>

On 04Jan2021 09:38, Weston Batey <3007645 at students.ankenyschools.org> wrote:
>My school is currently using edhesive to do python work and I need help
>answering this question. I am in 8.6 arrays as parameters. A ___________ is
>a variable used to pass information to a method.

The clue's in the title :-)

I'm guessing you're doing this, or something like it:

    https://ochoaprep.erusd.org/apps/classes/916418/assignments/

There's a PDF there associated with the Unit 9 quiz.

This is just a terminology question, and since the handout PDF above is 
pretty... short on context:

The word you want is "parameter". When you write a function like this:

    def mul(a, b):
        return a * b

the variables "a" and "b" come from the function argumments, generally 
called "parameters". When you call it, for example:

    x = mul(3, 2)

the function parameters "a" and "b" take on the values 3 and 2 
respectively, which it then multiplies together and returns as the 
function result. The calling code above receives that result and stores 
it in its own variable "x".

Note that Python variable are _references_. In the larger context of 
arrays as parameters, an array variable is a _reference_ to the array 
itself in memory. So when you do something like this:

    x = [1, 2, 3]

and call a function f(x), the function receives a copy of the 
_reference_, not a copy of the array. That reference is pointing to the 
same array as the caller, which means that the function may modify the 
contents of the array directly and the caller will see the changes.

Also have a read of the python docs:

    https://docs.python.org/3/glossary.html?highlight=glossary#term-arguments
    https://docs.python.org/3/glossary.html?highlight=glossary#term-parameter
    https://docs.python.org/3/faq/programming.html#faq-argument-vs-parameter

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

From alan.gauld at yahoo.co.uk  Mon Jan  4 16:48:19 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 4 Jan 2021 21:48:19 +0000
Subject: [Tutor] Help!
In-Reply-To: <X/OGKdx2X8z+ma2+@cskk.homeip.net>
References: <CAMF4QiEJfwhKvKBFeZoAfZmQBghVWSUXStgp=_Hqb-11h39Y2w@mail.gmail.com>
 <X/OGKdx2X8z+ma2+@cskk.homeip.net>
Message-ID: <rt02f6$qo6$1@ciao.gmane.io>

On 04/01/2021 21:18, Cameron Simpson wrote:

> The word you want is "parameter". When you write a function like this:
> 
>     def mul(a, b):
>         return a * b
> 
> the variables "a" and "b" come from the function argumments, generally 
> called "parameters". When you call it, for example:
> 
>     x = mul(3, 2)
> 
> the function parameters "a" and "b" take on the values 3 and 2 
> respectively, 

This is one bit of computing terminology that often confuses
learners (and sometimes more experienced practitioners who
should know better!)

In the example above a and b are *parameters* of the function mul()
They are the placeholders for values passed by the functions callers.

When the function is called as mul(3,2) the values 3 and 2 are the
functions *arguments*. So arguments are passed into a function when you
call it and the parameters are the parts of the function definition
which take on (or receive) the values of those arguments.

It may sound like a subtle distinction but when discussing how functions
are defined and used the separation of terms becomes significant.

Note:
Just to really confuse things, some text books use the term "formal
arguments" instead of parameters. Personally I find "formal arguments"
and "arguments" far too close for comfort so I always use
parameters/arguments.


-- 
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 unix.co at gmail.com  Fri Jan  8 04:44:42 2021
From: unix.co at gmail.com (Umar Draz)
Date: Fri, 8 Jan 2021 14:44:42 +0500
Subject: [Tutor] Remove duplicate values from dictionary without removing key
Message-ID: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>

I want to replace duplicate values with empty "" in my dictionary. Here is
my original dictionary.

items = [
    {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
    {'client': 'xyz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 100},
    {'client': 'xyz','name': "Alexander Lukashenko", 'rating': 3.1,
'total': 100},
    {'client': 'xyz', 'name': "Miguel D?az-Canel", 'rating': 0.32,
'total': 100},
    {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
    {'client': 'udz', 'name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 100},
    {'client': 'udz', 'name': "Alexander Lukashenko", 'rating': 3.1,
'total': 150},
    {'client': 'udz', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': 150}
]

Now I want to create another dict with like this

items = [
    {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
    {'client': '','name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
    {'client': '','name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
    {'client': '', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''},
    {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
    {'client': '', 'name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
    {'client': '', 'name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
    {'client': '', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''}
]


Would you please help me how I can do this?

From alan.gauld at yahoo.co.uk  Fri Jan  8 07:14:21 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 8 Jan 2021 12:14:21 +0000
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
Message-ID: <rt9iat$stp$1@ciao.gmane.io>

On 08/01/2021 09:44, Umar Draz wrote:
> I want to replace duplicate values with empty "" in my dictionary. Here is
> my original dictionary.

It is extremely important in programming to use terms accurately.
You do not in fact have a dictionary, you have a list of dictionaries.
You do not want to replace duplicate values you want to replace single
field values where previous dictionaries have had the same value in
the same field. (If the criteria is more complex than that then
please spell it out in detail, that will make the code you need
to write more obvious)

Using the correct terms means you can create an accurate description
of your problem. Very often when you do that the solution will
become clearer.

In your case you want in pseudo code:

for each dictionary in the list
    for each field in the dictionary
       check if the value has already been seen
       if so replace the value with ""
       else store the value for future reference but do not change it.

Can you convert that pseudo code to Python?
Hint: For the previously seen values you could store them
      in lists in another, separate dictionary called seen:

seen = { "client":[], "name:[], "rating":[],....}

It should be relatively simple. If you have difficulty get back to us.

> items = [
>     {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
>     {'client': 'xyz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
> 'total': 100},
>     {'client': 'xyz','name': "Alexander Lukashenko", 'rating': 3.1,
> 'total': 100},
>     {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
>     {'client': 'udz', 'name': "Abdelmadjid Tebboune", 'rating': 4.0,
> 'total': 100},

> Now I want to create another dict with like this
> 
> items = [
>     {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
>     {'client': '','name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
>     {'client': '','name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
>     {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
>     {'client': '', 'name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},


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



From alan.gauld at yahoo.co.uk  Fri Jan  8 08:25:52 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 8 Jan 2021 13:25:52 +0000
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
Message-ID: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>

Please always use Reply All or reply List when reponding to list emails,
otherwise
they only go to the individual person who posted. I've CCd the list on
this reply.


On 08/01/2021 12:24, Umar Draz wrote:
> I am totally?new in Python, so if there is any example then it will be
> helpful for me,
>
OK, Lets take it one bit at a time.

In your case you want in pseudo code:


seen = { "client":[], "name:[], "rating":[], "total": [] }

>
>     for each dictionary in the list
>
for dic in items:

>     ? ? for each field in the dictionary
>
???? for field,value in dic.items():

>     ? ? ? ?check if the value has already been seen
>
??????????? if value in seen[field]:

>     ? ? ?? if so replace the value with ""
>
???????????????? dic[field] = ""

>     ? ? ?? else store the value for future reference but do not change it.
>
??????????? else: seen[field].append(value)


And that should work, although I haven't tested it so there may be some
minor errors,
which I'll leave as an exercise! :-).

Try it and if you can't get it to work come back with a cut n paste of
your exact
code plus any error messages you get (in full)

-- 

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


From alan.gauld at yahoo.co.uk  Fri Jan  8 08:50:56 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 8 Jan 2021 13:50:56 +0000
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
 <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
Message-ID: <rt9o00$o6v$1@ciao.gmane.io>

On 08/01/2021 13:25, Alan Gauld via Tutor wrote:

> OK, Lets take it one bit at a time.

To summarize and make it easier to use in your existing code I;ll turn
it into a function:

def remove_duplicate_values(dict_list):
    seen = {}
    for key in dict_list[0].keys():
        seen[key] = []

    for dic in dict_list:
   ???? for field,value in dic.items():
??????????? if value in seen[field]:
?????????????? dic[field] = ""
??????????? else: seen[field].append(value)
    return dict_list

Call it with:

items = remove_duplicate_values(items)


That function should work for any list of similar dictionaries.
But again untested!

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



From alan.gauld at yahoo.co.uk  Fri Jan  8 10:25:00 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 8 Jan 2021 15:25:00 +0000
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <CAAKRE70AMYUuw+8cYu6TR-wm2vzy9v3tURNgkCRKEj2OpvC_Wg@mail.gmail.com>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
 <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
 <rt9o00$o6v$1@ciao.gmane.io>
 <CAAKRE7380tMu_9DdMX2S5rYZLcgBDyKwgZ7F6_OSCKnPq=McqQ@mail.gmail.com>
 <CAAKRE70AMYUuw+8cYu6TR-wm2vzy9v3tURNgkCRKEj2OpvC_Wg@mail.gmail.com>
Message-ID: <b6c2408d-5823-df22-44e6-f894c534dfcc@yahoo.co.uk>


On 08/01/2021 14:18, Umar Draz wrote:
> Hi Alan
>
> I have changed the function and now it is working as I want
>
> *def**remove_duplicate_values*(dict_list):
>
> ? ? seen = {}
>
> ? ? *for*key *in*dict_list[0].keys():
>
> ? ? ? ? seen[key] = []
>
>
> ? ? *for*dic *in*dict_list:
>
> ? ? ? ? *for*field,value *in*dic.items():
>
> ? ? ? ? ? ? *if*field == *'client'*:
>
> ? ? ? ? ? ? ? *if*value *in*seen[field]:
>
> ?? ? ? ? ? ? ? ? dic[field] = ""
>
> ? ? ? ? ? ? ? *else*: seen[field].append(value)
>
> ? ? *return*dict_list
>
>
OK, For a single field I would suggest simplifying it slightly.

*def**remove_duplicate_values*(dict_list, field):

?? seen = []


? ? *for*dic *in*dict_list:? ? ? ? ? ?
??????? *if*dic[field]*in*seen:

?? ? ? ? dic[field] = ""

? ? ? *else*: seen.append(value)

?? *return*dict_list


That way you can still use it for other fields if

necessary and for 'client' simply call it as


items = remove_duplicate_values(items,"client")


To remove dups in multiple fields just call it
repeated times with different field names. (Notice
that your original mail's example removed more
than the client field duplicates!)


-- 

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  Fri Jan  8 10:56:19 2021
From: david at graniteweb.com (David Rock)
Date: Fri, 8 Jan 2021 09:56:19 -0600
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
Message-ID: <20210108155619.GF25370@apple.graniteweb.com>

* Umar Draz <unix.co at gmail.com> [2021-01-08 14:44]:
> I want to replace duplicate values with empty "" in my dictionary. Here is
> my original dictionary.
> 
> Now I want to create another dict with like this
> 
> items = [
>     {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
>     {'client': '','name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
>     {'client': '','name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
>     {'client': '', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''},
>     {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
>     {'client': '', 'name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
>     {'client': '', 'name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
>     {'client': '', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''}
> ]

I'm very curious about the end goal in your question.  Are you sure you
want to remove the client value?  Will that break a relationship between
items?  This looks to me like what you actually want is a dictionary of
clients/names:

clients = {
        'xyz': [
            {'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
            {'name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
            {'name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
            {'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''},
        ],
        'udz': [ 
            {'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
            {'name': "Abdelmadjid Tebboune", 'rating': 4.0, 'total': ''},
            {'name': "Alexander Lukashenko", 'rating': 3.1, 'total': ''},
            {'name': "Miguel D?az-Canel", 'rating': 0.32, 'total': ''}
        ]
}

so rather than loop through and remove information, just add items to
the appropriate client list?

-- 
David Rock
david at graniteweb.com

From unix.co at gmail.com  Fri Jan  8 08:50:59 2021
From: unix.co at gmail.com (Umar Draz)
Date: Fri, 8 Jan 2021 18:50:59 +0500
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
 <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
Message-ID: <CAAKRE73UQtRH1D49ap5wB4e5iYF5YVn3Ta78D_Jb6+rjxgMS+A@mail.gmail.com>

Here is the Code

from pprint import pprint


items = [

    {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},

    {'client': 'xyz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 100},

    {'client': 'xyz','name': "Alexander Lukashenko", 'rating': 3.1,
'total': 100},

    {'client': 'xyz', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total':
100},

    {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},

    {'client': 'udz', 'name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 150},

    {'client': 'udz', 'name': "Alexander Lukashenko", 'rating': 3.1,
'total': 150},

    {'client': 'udz', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total':
150}

]


seen = { "client":[], "name":[], "rating":[], "total": [] }


for dic in items:

  for field,value in dic.items():

    if value in seen[field]:

      dic[field] = ""

    else:

      seen[field].append(value)


pprint(seen)



and here is the output which is completely different then I had expected.



{'client': ['xyz', 'udz'],

 'name': ['Ilir Meta',

          'Abdelmadjid Tebboune',

          'Alexander Lukashenko',

          'Miguel D?az-Canel'],

 'rating': [0.06, 4.0, 3.1, 0.32],

 'total': [100, 150]}

On Fri, Jan 8, 2021 at 6:25 PM Alan Gauld <alan.gauld at yahoo.co.uk> wrote:

> Please always use Reply All or reply List when reponding to list emails,
> otherwise
> they only go to the individual person who posted. I've CCd the list on
> this reply.
>
>
> On 08/01/2021 12:24, Umar Draz wrote:
> > I am totally new in Python, so if there is any example then it will be
> > helpful for me,
> >
> OK, Lets take it one bit at a time.
>
> In your case you want in pseudo code:
>
>
> seen = { "client":[], "name:[], "rating":[], "total": [] }
>
> >
> >     for each dictionary in the list
> >
> for dic in items:
>
> >         for each field in the dictionary
> >
>      for field,value in dic.items():
>
> >            check if the value has already been seen
> >
>             if value in seen[field]:
>
> >            if so replace the value with ""
> >
>                  dic[field] = ""
>
> >            else store the value for future reference but do not change
> it.
> >
>             else: seen[field].append(value)
>
>
> And that should work, although I haven't tested it so there may be some
> minor errors,
> which I'll leave as an exercise! :-).
>
> Try it and if you can't get it to work come back with a cut n paste of
> your exact
> code plus any error messages you get (in full)
>
> --
>
> 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
>
>

-- 
Umar Draz

From unix.co at gmail.com  Fri Jan  8 09:03:50 2021
From: unix.co at gmail.com (Umar Draz)
Date: Fri, 8 Jan 2021 19:03:50 +0500
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <rt9o00$o6v$1@ciao.gmane.io>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
 <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
 <rt9o00$o6v$1@ciao.gmane.io>
Message-ID: <CAAKRE7380tMu_9DdMX2S5rYZLcgBDyKwgZ7F6_OSCKnPq=McqQ@mail.gmail.com>

Hi Alan

The function you gave me worked but it has a little issue, here is the code

from pprint import pprint


def remove_duplicate_values(dict_list):

    seen = {}

    for key in dict_list[0].keys():

        seen[key] = []


    for dic in dict_list:

        for field,value in dic.items():

            if value in seen[field]:

               dic[field] = ""

            else: seen[field].append(value)

    return dict_list


items = [

    {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},

    {'client': 'xyz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 100},

    {'client': 'xyz','name': "Alexander Lukashenko", 'rating': 3.1,
'total': 100},

    {'client': 'xyz', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total':
100},

    {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},

    {'client': 'udz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
'total': 150},

    {'client': 'udz','name': "Alexander Lukashenko", 'rating': 3.1,
'total': 150},

    {'client': 'udz', 'name': "Miguel D?az-Canel", 'rating': 0.32, 'total':
150},

]


items = remove_duplicate_values(items)


pprint(items)



Here is the output


[{'client': 'xyz', 'name': 'Ilir Meta', 'rating': 0.06, 'total': 100},

 {'client': '', 'name': 'Abdelmadjid Tebboune', 'rating': 4.0, 'total': ''},

 {'client': '', 'name': 'Alexander Lukashenko', 'rating': 3.1, 'total': ''},

 {'client': '', 'name': 'Miguel D?az-Canel', 'rating': 0.32, 'total': ''},

 {'client': 'udz', 'name': '', 'rating': '', 'total': '150'},

 {'client': '', 'name': '', 'rating': '', 'total': ''},

 {'client': '', 'name': '', 'rating': '', 'total': ''},

 {'client': '', 'name': '', 'rating': '', 'total': ''}]



You can see the name and rating values also marked empty for client (udz),
now is it possible that the function only check client key



On Fri, Jan 8, 2021 at 6:51 PM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 08/01/2021 13:25, Alan Gauld via Tutor wrote:
>
> > OK, Lets take it one bit at a time.
>
> To summarize and make it easier to use in your existing code I;ll turn
> it into a function:
>
> def remove_duplicate_values(dict_list):
>     seen = {}
>     for key in dict_list[0].keys():
>         seen[key] = []
>
>     for dic in dict_list:
>         for field,value in dic.items():
>             if value in seen[field]:
>                dic[field] = ""
>             else: seen[field].append(value)
>     return dict_list
>
> Call it with:
>
> items = remove_duplicate_values(items)
>
>
> That function should work for any list of similar dictionaries.
> But again untested!
>
> --
> 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
>


-- 
Umar Draz

From unix.co at gmail.com  Fri Jan  8 09:18:48 2021
From: unix.co at gmail.com (Umar Draz)
Date: Fri, 8 Jan 2021 19:18:48 +0500
Subject: [Tutor] Remove duplicate values from dictionary without
 removing key
In-Reply-To: <CAAKRE7380tMu_9DdMX2S5rYZLcgBDyKwgZ7F6_OSCKnPq=McqQ@mail.gmail.com>
References: <CAAKRE726fcpD0=MqYGY8aX=UtWVT8A6GKg9hOuxWb42pOOqCRw@mail.gmail.com>
 <rt9iat$stp$1@ciao.gmane.io>
 <CAAKRE715XXLdktSx4j7ERU8Baar87F2Md8AVLdFcX6aKNaWHcA@mail.gmail.com>
 <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk>
 <rt9o00$o6v$1@ciao.gmane.io>
 <CAAKRE7380tMu_9DdMX2S5rYZLcgBDyKwgZ7F6_OSCKnPq=McqQ@mail.gmail.com>
Message-ID: <CAAKRE70AMYUuw+8cYu6TR-wm2vzy9v3tURNgkCRKEj2OpvC_Wg@mail.gmail.com>

Hi Alan

I have changed the function and now it is working as I want

*def** remove_duplicate_values*(dict_list):

    seen = {}

    *for* key *in* dict_list[0].keys():

        seen[key] = []


    *for* dic *in* dict_list:

        *for* field,value *in* dic.items():

            *if* field == *'client'*:

              *if* value *in* seen[field]:

                 dic[field] = ""

              *else*: seen[field].append(value)

    *return* dict_list



Thanks for your help

On Fri, Jan 8, 2021 at 7:03 PM Umar Draz <unix.co at gmail.com> wrote:

> Hi Alan
>
> The function you gave me worked but it has a little issue, here is the code
>
> from pprint import pprint
>
>
> def remove_duplicate_values(dict_list):
>
>     seen = {}
>
>     for key in dict_list[0].keys():
>
>         seen[key] = []
>
>
>     for dic in dict_list:
>
>         for field,value in dic.items():
>
>             if value in seen[field]:
>
>                dic[field] = ""
>
>             else: seen[field].append(value)
>
>     return dict_list
>
>
> items = [
>
>     {'client': 'xyz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 100},
>
>     {'client': 'xyz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
> 'total': 100},
>
>     {'client': 'xyz','name': "Alexander Lukashenko", 'rating': 3.1,
> 'total': 100},
>
>     {'client': 'xyz', 'name': "Miguel D?az-Canel", 'rating': 0.32,
> 'total': 100},
>
>     {'client': 'udz', 'name': "Ilir Meta", 'rating': 0.06, 'total': 150},
>
>     {'client': 'udz','name': "Abdelmadjid Tebboune", 'rating': 4.0,
> 'total': 150},
>
>     {'client': 'udz','name': "Alexander Lukashenko", 'rating': 3.1,
> 'total': 150},
>
>     {'client': 'udz', 'name': "Miguel D?az-Canel", 'rating': 0.32,
> 'total': 150},
>
> ]
>
>
> items = remove_duplicate_values(items)
>
>
> pprint(items)
>
>
>
> Here is the output
>
>
> [{'client': 'xyz', 'name': 'Ilir Meta', 'rating': 0.06, 'total': 100},
>
>  {'client': '', 'name': 'Abdelmadjid Tebboune', 'rating': 4.0, 'total':
> ''},
>
>  {'client': '', 'name': 'Alexander Lukashenko', 'rating': 3.1, 'total':
> ''},
>
>  {'client': '', 'name': 'Miguel D?az-Canel', 'rating': 0.32, 'total': ''},
>
>  {'client': 'udz', 'name': '', 'rating': '', 'total': '150'},
>
>  {'client': '', 'name': '', 'rating': '', 'total': ''},
>
>  {'client': '', 'name': '', 'rating': '', 'total': ''},
>
>  {'client': '', 'name': '', 'rating': '', 'total': ''}]
>
>
>
> You can see the name and rating values also marked empty for client (udz),
> now is it possible that the function only check client key
>
>
>
> On Fri, Jan 8, 2021 at 6:51 PM Alan Gauld via Tutor <tutor at python.org>
> wrote:
>
>> On 08/01/2021 13:25, Alan Gauld via Tutor wrote:
>>
>> > OK, Lets take it one bit at a time.
>>
>> To summarize and make it easier to use in your existing code I;ll turn
>> it into a function:
>>
>> def remove_duplicate_values(dict_list):
>>     seen = {}
>>     for key in dict_list[0].keys():
>>         seen[key] = []
>>
>>     for dic in dict_list:
>>         for field,value in dic.items():
>>             if value in seen[field]:
>>                dic[field] = ""
>>             else: seen[field].append(value)
>>     return dict_list
>>
>> Call it with:
>>
>> items = remove_duplicate_values(items)
>>
>>
>> That function should work for any list of similar dictionaries.
>> But again untested!
>>
>> --
>> 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
>>
>
>
> --
> Umar Draz
>


-- 
Umar Draz

From Chukwunonso.Oranyeli at ssfs.org  Mon Jan 11 17:34:00 2021
From: Chukwunonso.Oranyeli at ssfs.org (Chukwunonso Oranyeli)
Date: Mon, 11 Jan 2021 22:34:00 +0000
Subject: [Tutor] Hello
Message-ID: <DM6PR12MB3658ECA8BB5DCE5EF9DFA277FAAB0@DM6PR12MB3658.namprd12.prod.outlook.com>

I am going to send my code. Right now I have a ball moving fast and bumping on the edges of my screen. I want the code to be set up in a way that when the ball hits the bottom of my screen, it resets back to the center. Could you help me with this?

import pygame

class Ball(pygame.sprite.Sprite):

    def __init__(self, color, windowWidth, windowHeight, radius,):
        # initialize sprite super class
        super().__init__()

        # finish setting the class variables to the parameters
        self.color = color
        self.windowWidth= windowWidth
        self.windowHeight= windowHeight
        self.radius= radius



        # Create a surface, get the rect coordinates, fill the surface with a white color (or whatever color the
        # background of your breakout game will be.
        self.image = pygame.Surface((self.radius*2,self.radius*2))
        pygame.draw.circle(self.image, self.color, (self.radius, self.radius), self.radius)

        self.rect =self.image.get_rect()

        self.x_speed = 5
        self.y_speed = 3



        # Add a circle to represent the ball to the surface just created. Just use the pygame.draw.circle method.
        # The surface will be self.image
        pygame.draw.circle(self.image, self.color, (self.radius, self.radius), self.radius)



        # Give the ball an initial speed. You will need a speed for the x direction and one for the y direction.
        self.x_speed= 5
        self.y_speed= 3







    def move(self):

       self.rect.x += self.x_speed
       self.rect.y += self.y_speed

       if self.rect.top < 0 or self.rect.bottom > self.windowWidth:
           self.y_speed = -self.y_speed

       if self.rect.left< 0 or self.rect.right > self.windowHeight:
           self.x_speed= -self.x_speed







From PyTutor at DancesWithMice.info  Mon Jan 11 19:11:13 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Tue, 12 Jan 2021 13:11:13 +1300
Subject: [Tutor] Hello
In-Reply-To: <DM6PR12MB3658ECA8BB5DCE5EF9DFA277FAAB0@DM6PR12MB3658.namprd12.prod.outlook.com>
References: <DM6PR12MB3658ECA8BB5DCE5EF9DFA277FAAB0@DM6PR12MB3658.namprd12.prod.outlook.com>
Message-ID: <755efd95-8e79-2012-4e43-bab57336e946@DancesWithMice.info>

On 12/01/2021 11.34, Chukwunonso Oranyeli via Tutor wrote:
> I am going to send my code. Right now I have a ball moving fast and bumping on the edges of my screen. I want the code to be set up in a way that when the ball hits the bottom of my screen, it resets back to the center. Could you help me with this?

We are not here to do 'homework' for you, but are happy to help you learn.


Is this code working correctly? ie when the ball reaches the left or
right side of the screen does it bounce?
NB the code-provided is incomplete. If the 'board' Rect is square, it
may appear to work correctly - but when you make it a rectangle (width
!= height) then it probably will not!


>     def move(self):
> 
>        self.rect.x += self.x_speed
>        self.rect.y += self.y_speed
> 
>        if self.rect.top < 0 or self.rect.bottom > self.windowWidth:
>            self.y_speed = -self.y_speed
> 
>        if self.rect.left< 0 or self.rect.right > self.windowHeight:
>            self.x_speed= -self.x_speed

The code appears to be handling a 'bounce'.

Here are some questions to answer, which will help you answer your own
question and to progress towards a solution:-

When we look at the left or right edges, are we considering the window's
height or its width?
(same question for top/bottom edges)

Which condition, or part of one of the conditions (above) detects when
the ball has hit the bottom of the screen?

NB This needs to become two separate conditions if touching the top of
the window should still result in a 'bounce'!

Once the bottom-bounce condition has been identified and separated, the
then-clause should be altered to re-position the ball, as desired.

Don't forget that as well as changing the ball's position, it may be
appropriate to think about its speed and direction (unless the ball
simply stops/returns to its starting position).


Try working through the above. Then let us know if you have a further
question, and post updated code/the final result.
-- 
Regards =dn

From s.molnar at sbcglobal.net  Tue Jan 12 14:32:36 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Tue, 12 Jan 2021 14:32:36 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
References: <5FFDF954.2080904.ref@sbcglobal.net>
Message-ID: <5FFDF954.2080904@sbcglobal.net>

Python3.7.3 on Debian Buster.

I have a large number of computational docking files from which I wish 
to extract results.

I have cobbled together a script that works, up to a point:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np

df = pd.read_csv('ligands_3')
num = [1,2,3,4,5,6,7,8,9,10]

for ligand in df:
     for i in num:
         name_in = "{}.{}.log".format(ligand, i)
         data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
         name_s = ligand+'-BE'
         f = open(name_s, 'a')
         f.write(str(data[0,1])+'\n')
         f.close()

For each ligand I run ten repetitions of the docking. The ligands_3 file 
contains three ligand names:

7-Phloroeckol
Aloeemodin
beta-Sitosterol

The code produces, for example, for the first ligand in the list:

-9.248153586
-9.174749259
-8.941017151
-9.162562472
-9.17411506
-9.217528128
-9.133030378
-9.182355251
-9.298771543
-9.300577161

Which happen to be correct.

The problem, though, is that the script does not go on to the next 
ligand in the list. Everything that I have found in Google results says 
that the script will iterate through the list.

What have I done or not done?

I will be most appreciate of suggestions. Thanks in advance.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From mats at wichmann.us  Tue Jan 12 14:57:24 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Tue, 12 Jan 2021 12:57:24 -0700
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <5FFDF954.2080904@sbcglobal.net>
References: <5FFDF954.2080904.ref@sbcglobal.net>
 <5FFDF954.2080904@sbcglobal.net>
Message-ID: <8a61e0e5-330b-d37b-b147-c138f79977e5@wichmann.us>

On 1/12/21 12:32 PM, Stephen P. Molnar wrote:
> Python3.7.3 on Debian Buster.
> 
> I have a large number of computational docking files from which I wish 
> to extract results.
> 
> I have cobbled together a script that works, up to a point:
> 
> #!/usr/bin/env python3
> # -*- coding: utf-8 -*-
> import pandas as pd
> import numpy as np
> 
> df = pd.read_csv('ligands_3')
> num = [1,2,3,4,5,6,7,8,9,10]
> 
> for ligand in df:
...
> For each ligand I run ten repetitions of the docking. The ligands_3 file 
> contains three ligand names:
> 
> 7-Phloroeckol
> Aloeemodin
> beta-Sitosterol
...
> The problem, though, is that the script does not go on to the next 
> ligand in the list. Everything that I have found in Google results says 
> that the script will iterate through the list.
> 
> What have I done or not done?

you're reading as a csv and trying to create a dataframe. are you 
getting what you expect?

print out what df is before you start using it.

From s.molnar at sbcglobal.net  Tue Jan 12 15:30:52 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Tue, 12 Jan 2021 15:30:52 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <8a61e0e5-330b-d37b-b147-c138f79977e5@wichmann.us>
References: <5FFDF954.2080904.ref@sbcglobal.net>
 <5FFDF954.2080904@sbcglobal.net>
 <8a61e0e5-330b-d37b-b147-c138f79977e5@wichmann.us>
Message-ID: <5FFE06FC.3070706@sbcglobal.net>



On 01/12/2021 02:57 PM, Mats Wichmann wrote:
> On 1/12/21 12:32 PM, Stephen P. Molnar wrote:
>> Python3.7.3 on Debian Buster.
>>
>> I have a large number of computational docking files from which I 
>> wish to extract results.
>>
>> I have cobbled together a script that works, up to a point:
>>
>> #!/usr/bin/env python3
>> # -*- coding: utf-8 -*-
>> import pandas as pd
>> import numpy as np
>>
>> df = pd.read_csv('ligands_3')
>> num = [1,2,3,4,5,6,7,8,9,10]
>>
>> for ligand in df:
> ..
>> For each ligand I run ten repetitions of the docking. The ligands_3 
>> file contains three ligand names:
>>
>> 7-Phloroeckol
>> Aloeemodin
>> beta-Sitosterol
> ..
>> The problem, though, is that the script does not go on to the next 
>> ligand in the list. Everything that I have found in Google results 
>> says that the script will iterate through the list.
>>
>> What have I done or not done?
>
> you're reading as a csv and trying to create a dataframe. are you 
> getting what you expect?

Yes. I get exactly what I was expecting.

See below.
>
> print out what df is before you start using it.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

=======================================================================
GWOVina version 1.0
Michael K. M. Wong & Shirley W. I. Siu

Computational Biology and Bioinformatics Lab
University of Macau

Visit http://cbbio.cis.umac.mo for more information.

GWOVina was developed based on the framework of AutoDock Vina.

For more information about Vina, please visit http://vina.scripps.edu.

=======================================================================

WARNING: The search space volume > 27000 Angstrom^3 (See FAQ)
Detected 8 CPUs
Reading input ... done.
Setting up the scoring function ... done.
Analyzing the binding site ... done.
Using random seed: -1915785459
Performing search ... done.

Refining results ... done.

mode |   affinity | dist from best mode
      | (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
    1    -9.248153586      0.000      0.000
    2    -8.770186166      4.382     11.138
    3    -8.711215213      2.155      9.423
    4    -8.693086289      5.334     11.567
    5    -8.669326608      4.935     11.596
    6    -8.438957983      4.145     10.894
    7    -8.224671047      2.364      8.799
    8    -8.202856331      4.968      9.419
    9    -8.198276007      2.291      8.099
Writing output ... done.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From cs at cskk.id.au  Tue Jan 12 16:44:15 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 13 Jan 2021 08:44:15 +1100
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <5FFDF954.2080904@sbcglobal.net>
References: <5FFDF954.2080904@sbcglobal.net>
Message-ID: <X/4YL8PJUI5DPMRO@cskk.homeip.net>

On 12Jan2021 14:32, Stephen P. Molnar <s.molnar at sbcglobal.net> wrote:
>Python3.7.3 on Debian Buster.
>
>I have a large number of computational docking files from which I wish 
>to extract results.
>
>I have cobbled together a script that works, up to a point:
>
>#!/usr/bin/env python3
># -*- coding: utf-8 -*-
>import pandas as pd
>import numpy as np
>
>df = pd.read_csv('ligands_3')

Did you print df here?

>num = [1,2,3,4,5,6,7,8,9,10]
>
>for ligand in df:

Did you print ligand here?

    
>    for i in num:
>        name_in = "{}.{}.log".format(ligand, i)

I'd write this as:

    name_in = f"{ligand}.{i}.log"

which I find more readable. Not relevant to your problem.

But wait, hang on? What's in your CSV file? It looks like ligands_3 is 
just a list of ligand names? Using pandas.read_csv seems like overkill 
if so. Maybe it does do what you thought.

However, looking at the pandas docs:

    https://pandas.pydata.org/pandas-docs/stable/user_guide/cookbook.html#cookbook-csv

suggests it does what you think it does.

But _print out ligand_! And earlier, print out df! See what they really 
are.

>        data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
>        name_s = ligand+'-BE'
>        f = open(name_s, 'a')
>        f.write(str(data[0,1])+'\n')
>        f.close()
>
>For each ligand I run ten repetitions of the docking. The ligands_3 
>file contains three ligand names:
>
>7-Phloroeckol
>Aloeemodin
>beta-Sitosterol
>
>The code produces, for example, for the first ligand in the list:
>
>-9.248153586
[...]
>-9.300577161
>
>Which happen to be correct.
>
>The problem, though, is that the script does not go on to the next 
>ligand in the list. Everything that I have found in Google results says 
>that the script will iterate through the list.

The script should iterate through the list. Superficially it looks good 
to me.

Print statements, they are your friend here. See what values you are 
getting at each stage.

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

From briannicholasperez114 at gmail.com  Wed Jan 13 02:03:23 2021
From: briannicholasperez114 at gmail.com (Brian Perez)
Date: Tue, 12 Jan 2021 23:03:23 -0800
Subject: [Tutor] Homework Help
Message-ID: <CAPQn6Hx3VAi_63V3xb2Mfgd3YBqmtjKz05xT-qQ-vhtObOf+oA@mail.gmail.com>

Hello,

Are you able to assist with a python assignment?

Thank you.

From pytutor at danceswithmice.info  Wed Jan 13 04:30:56 2021
From: pytutor at danceswithmice.info (dn)
Date: Wed, 13 Jan 2021 22:30:56 +1300
Subject: [Tutor] Homework Help
In-Reply-To: <CAPQn6Hx3VAi_63V3xb2Mfgd3YBqmtjKz05xT-qQ-vhtObOf+oA@mail.gmail.com>
References: <CAPQn6Hx3VAi_63V3xb2Mfgd3YBqmtjKz05xT-qQ-vhtObOf+oA@mail.gmail.com>
Message-ID: <8c02de04-8321-1c3e-b7e9-111031bfab55@DancesWithMice.info>

On 13/01/2021 20.03, Brian Perez wrote:
> Hello,
> 
> Are you able to assist with a python assignment?
> 
> Thank you.


Sure - but we won't do the assignment for you!

Please tell us the question - if you can mention the book or course,
even better. The show us what code you have so far, and what's holding
you up...

-- 
Regards =dn

From s.molnar at sbcglobal.net  Wed Jan 13 08:39:38 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Wed, 13 Jan 2021 08:39:38 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <X/4YL8PJUI5DPMRO@cskk.homeip.net>
References: <5FFDF954.2080904@sbcglobal.net> <X/4YL8PJUI5DPMRO@cskk.homeip.net>
Message-ID: <5FFEF81A.2030006@sbcglobal.net>



On 01/12/2021 04:44 PM, Cameron Simpson wrote:
> On 12Jan2021 14:32, Stephen P. Molnar <s.molnar at sbcglobal.net> wrote:
>> Python3.7.3 on Debian Buster.
>>
>> I have a large number of computational docking files from which I wish
>> to extract results.
>>
>> I have cobbled together a script that works, up to a point:
>>
>> #!/usr/bin/env python3
>> # -*- coding: utf-8 -*-
>> import pandas as pd
>> import numpy as np
>>
>> df = pd.read_csv('ligands_3')
> Did you print df here?
>
>> num = [1,2,3,4,5,6,7,8,9,10]
>>
>> for ligand in df:
> Did you print ligand here?
>
>      
>>     for i in num:
>>         name_in = "{}.{}.log".format(ligand, i)
> I'd write this as:
>
>      name_in = f"{ligand}.{i}.log"
>
> which I find more readable. Not relevant to your problem.
>
> But wait, hang on? What's in your CSV file? It looks like ligands_3 is
> just a list of ligand names? Using pandas.read_csv seems like overkill
> if so. Maybe it does do what you thought.
>
> However, looking at the pandas docs:
>
>      https://pandas.pydata.org/pandas-docs/stable/user_guide/cookbook.html#cookbook-csv
>
> suggests it does what you think it does.
>
> But _print out ligand_! And earlier, print out df! See what they really
> are.
>
>>         data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
>>         name_s = ligand+'-BE'
>>         f = open(name_s, 'a')
>>         f.write(str(data[0,1])+'\n')
>>         f.close()
>>
>> For each ligand I run ten repetitions of the docking. The ligands_3
>> file contains three ligand names:
>>
>> 7-Phloroeckol
>> Aloeemodin
>> beta-Sitosterol
>>
>> The code produces, for example, for the first ligand in the list:
>>
>> -9.248153586
> [...]
>> -9.300577161
>>
>> Which happen to be correct.
>>
>> The problem, though, is that the script does not go on to the next
>> ligand in the list. Everything that I have found in Google results says
>> that the script will iterate through the list.
> The script should iterate through the list. Superficially it looks good
> to me.
>
> Print statements, they are your friend here. See what values you are
> getting at each stage.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>
>
Thanks for the reply.

1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3import pandas as pd
4import numpy as np
5
6df = pd.read_csv('ligands_3')
7num = [1,2,3,4,5,6,7,8,9,10]
8
9for ligand in df:
10    for i in num:
11       name_in = "{}.{}.log".format(ligand, i)
12        data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
13        name_s = ligand+'-BE'
14        f = open(name_s, 'a')
15        f.write(str(data[0,1])+'\n')
16        f.close()

I have added the line numbers above so that I can address the results of 
what I have done (s0 far) a copy of the python script is attached, as 
well as the input files that are used to test the script.

Now, I have inserted print statements in various places in the code in 
order to check what is being written.

When I run the code I get what I expected.  I commented out every line 
below each print statement. I inserted a print statement to print the  
result of line 12 and got the record that I saved in line 15. When I ran 
the complete code it printed out everything that I expected and wrote 
the file 7-Phloroeckol-BE.

At this point in the testing I ran the code line by line (printing out 
everything that happened) and got an interesting result on the execution 
of line 9 as well as the remaining lines of code.

import pandas as pd

import numpy as np

df = pd.read_csv('ligands_3')

num = [1,2,3,4,5,6,7,8,9,10]

for ligand in df:
   File "<ipython-input-5-269745371905>", line 1
     for ligand in df:
                      ^
SyntaxError: unexpected EOF while parsing


for i in num:
   File "<ipython-input-6-e91b9883e5b7>", line 1
     for i in num:
                  ^
SyntaxError: unexpected EOF while parsing


name_in = "{}.{}.log".format(ligand, i)
Traceback (most recent call last):

   File "<ipython-input-7-6ad0f8600c09>", line 1, in <module>
     name_in = "{}.{}.log".format(ligand, i)

NameError: name 'ligand' is not defined


data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
Traceback (most recent call last):

   File "<ipython-input-8-1bf8be5d1c3e>", line 1, in <module>
     data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)

NameError: name 'name_in' is not defined


name_s = ligand+'-BE'
Traceback (most recent call last):

   File "<ipython-input-9-cb0dd32021e3>", line 1, in <module>
     name_s = ligand+'-BE'

NameError: name 'ligand' is not defined


f = open(name_s, 'a')
Traceback (most recent call last):

   File "<ipython-input-10-8d5f8af45a47>", line 1, in <module>
     f = open(name_s, 'a')

NameError: name 'name_s' is not defined


f.write(str(data[0,1])+'\n')
Traceback (most recent call last):

   File "<ipython-input-11-894fa2631352>", line 1, in <module>
     f.write(str(data[0,1])+'\n')

AttributeError: 'builtin_function_or_method' object has no attribute 'write'


f.close()
Traceback (most recent call last):

   File "<ipython-input-12-b5edb7b78a9a>", line 1, in <module>
     f.close()

AttributeError: 'builtin_function_or_method' object has no attribute 'close'

I don't have the faintest idea as to what the trouble is.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From alan.gauld at yahoo.co.uk  Wed Jan 13 10:36:40 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 13 Jan 2021 15:36:40 +0000
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <5FFEF81A.2030006@sbcglobal.net>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
Message-ID: <rtn428$136k$1@ciao.gmane.io>

On 13/01/2021 13:39, Stephen P. Molnar wrote:

> At this point in the testing I ran the code line by line (printing out 
> everything that happened) and got an interesting result on the execution 
> of line 9 as well as the remaining lines of code.

I'm not sure what you mean by that?
It looks like you typed it into the iPython interpreter?
Is that correct? If so the first error will cause all
the subsequent ones since the preceding code is effectively
not there.

> for ligand in df:
>    File "<ipython-input-5-269745371905>", line 1
>      for ligand in df:
>                       ^
> SyntaxError: unexpected EOF while parsing

I have no idea why yoiu are getting this but it could be an
ipython issue. Try running it in the regular pythopn interpreter,
or better still just as a script with actual print() statements
in it. When debugging reduce the number of variables to the
minimum and that means using the basic interpreter with a file.


> for i in num:
>    File "<ipython-input-6-e91b9883e5b7>", line 1
>      for i in num:
>                   ^
> SyntaxError: unexpected EOF while parsing

Again I'm not sure why. Looks like the same problem as above.

>    File "<ipython-input-7-6ad0f8600c09>", line 1, in <module>
>      name_in = "{}.{}.log".format(ligand, i)
> 
> NameError: name 'ligand' is not defined

This is just because the for line above failed so ligand never
got created.

Try putting the print statements into the code to print:
- df - potentially big, but at least a sample of it(use slicing maybe?)
- ligand - should see each value as the loop iterates - ie. N values
- name_in - should be different for each iteration - 10xN in total
- name_s - one per ligand - N values
- data[0,1]  - one per iteration, check against file contents

Show us the output.

-- 
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 Jan 13 10:39:04 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 13 Jan 2021 15:39:04 +0000
Subject: [Tutor] Homework Help
In-Reply-To: <CAPQn6Hx3VAi_63V3xb2Mfgd3YBqmtjKz05xT-qQ-vhtObOf+oA@mail.gmail.com>
References: <CAPQn6Hx3VAi_63V3xb2Mfgd3YBqmtjKz05xT-qQ-vhtObOf+oA@mail.gmail.com>
Message-ID: <rtn46o$136k$2@ciao.gmane.io>

On 13/01/2021 07:03, Brian Perez wrote:
> Hello,
> 
> Are you able to assist with a python assignment?


Yes, but the key word is assist.
We will review code, answer questions, offer suggestions.
But we will not do the assignment for you.

Show us any code you write even (especially!) if it doesn't work.

Show us any error messages you get (in full).


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



From s.molnar at sbcglobal.net  Wed Jan 13 11:28:14 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Wed, 13 Jan 2021 11:28:14 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <rtn428$136k$1@ciao.gmane.io>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io>
Message-ID: <5FFF1F9E.5010806@sbcglobal.net>



On 01/13/2021 10:36 AM, Alan Gauld via Tutor wrote:
> On 13/01/2021 13:39, Stephen P. Molnar wrote:
>
>> At this point in the testing I ran the code line by line (printing out
>> everything that happened) and got an interesting result on the execution
>> of line 9 as well as the remaining lines of code.
> I'm not sure what you mean by that?
> It looks like you typed it into the iPython interpreter?
> Is that correct? If so the first error will cause all
> the subsequent ones since the preceding code is effectively
> not there.
>
>> for ligand in df:
>>     File "<ipython-input-5-269745371905>", line 1
>>       for ligand in df:
>>                        ^
>> SyntaxError: unexpected EOF while parsing
> I have no idea why yoiu are getting this but it could be an
> ipython issue. Try running it in the regular pythopn interpreter,
> or better still just as a script with actual print() statements
> in it. When debugging reduce the number of variables to the
> minimum and that means using the basic interpreter with a file.
>
>
>> for i in num:
>>     File "<ipython-input-6-e91b9883e5b7>", line 1
>>       for i in num:
>>                    ^
>> SyntaxError: unexpected EOF while parsing
> Again I'm not sure why. Looks like the same problem as above.
>
>>     File "<ipython-input-7-6ad0f8600c09>", line 1, in <module>
>>       name_in = "{}.{}.log".format(ligand, i)
>>
>> NameError: name 'ligand' is not defined
> This is just because the for line above failed so ligand never
> got created.
>
> Try putting the print statements into the code to print:
> - df - potentially big, but at least a sample of it(use slicing maybe?)
> - ligand - should see each value as the loop iterates - ie. N values
> - name_in - should be different for each iteration - 10xN in total
> - name_s - one per ligand - N values
> - data[0,1]  - one per iteration, check against file contents
>
> Show us the output.
>
Thank you for your reply.

Here is the code as edited:

runfile('/home/comp/Apps/EMSKE/PythonSoftware/Test/SARS-CoV-2a/ExtractVinaActivity.py', 
wdir='/home/comp/Apps/EMSKE/PythonSoftware/Test/SARS-CoV-2a', 
current_namespace=True)
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
1
7-Phloroeckol.1.log
[[ 1.         -9.24815359  0.          0.        ]
  [ 2.         -8.77018617  4.382      11.138     ]
  [ 3.         -8.71121521  2.155       9.423     ]
  [ 4.         -8.69308629  5.334      11.567     ]
  [ 5.         -8.66932661  4.935      11.596     ]
  [ 6.         -8.43895798  4.145      10.894     ]
  [ 7.         -8.22467105  2.364       8.799     ]
  [ 8.         -8.20285633  4.968       9.419     ]
  [ 9.         -8.19827601  2.291       8.099     ]]
7-Phloroeckol-BE
2
7-Phloroeckol.2.log
[[ 1.         -9.17474926  0.          0.        ]
  [ 2.         -8.76125135  4.477      11.177     ]
  [ 3.         -8.62503496  2.549       9.246     ]
  [ 4.         -8.51929251  5.321      10.904     ]
  [ 5.         -8.32529487  6.085      12.541     ]
  [ 6.         -8.27908207  6.051      12.457     ]
  [ 7.         -8.23362526  5.207      11.747     ]
  [ 8.         -8.22360117  5.284      11.396     ]
  [ 9.         -8.1552274   4.603      11.329     ]]
7-Phloroeckol-BE
3
7-Phloroeckol.3.log
[[ 1.         -8.94101715  0.          0.        ]
  [ 2.         -8.14939511  1.608       2.504     ]
  [ 3.         -8.12218651  2.139       3.186     ]
  [ 4.         -7.95106339 19.754      23.455     ]
  [ 5.         -7.94903298  1.795       3.034     ]
  [ 6.         -7.87858203  2.159       2.52      ]
  [ 7.         -7.84398855  2.244       3.116     ]
  [ 8.         -7.83202941  2.66        4.225     ]
  [ 9.         -7.70585579 27.441      32.52      ]]
7-Phloroeckol-BE
4
7-Phloroeckol.4.log
[[ 1.         -9.16256247  0.          0.        ]
  [ 2.         -9.00875388 17.317      22.896     ]
  [ 3.         -8.76733608  4.486      11.171     ]
  [ 4.         -8.67364017  5.072      11.659     ]
  [ 5.         -8.52560114  4.954      11.513     ]
  [ 6.         -8.31454518  5.833      12.473     ]
  [ 7.         -8.17565187  4.665      11.309     ]
  [ 8.         -8.1713394   3.529      10.53      ]
  [ 9.         -8.14095062  2.225       9.547     ]]
7-Phloroeckol-BE
5
7-Phloroeckol.5.log
[[ 1.         -9.17411506  0.          0.        ]
  [ 2.         -8.8841462   5.333      11.643     ]
  [ 3.         -8.77081732  4.476      11.169     ]
  [ 4.         -8.62460864  2.552       9.244     ]
  [ 5.         -8.44033143  5.428      11.144     ]
  [ 6.         -8.33375966  5.844      12.486     ]
  [ 7.         -8.30255093  6.09       12.539     ]
  [ 8.         -8.15969455  4.608      11.328     ]
  [ 9.         -8.12005716  5.161      11.509     ]]
7-Phloroeckol-BE
6
7-Phloroeckol.6.log
[[ 1.         -9.21752813  0.          0.        ]
  [ 2.         -8.77520263  4.762       8.699     ]
  [ 3.         -8.68887368  4.926      11.579     ]
  [ 4.         -8.62601653  2.44        9.186     ]
  [ 5.         -8.59648372  5.352      11.044     ]
  [ 6.         -8.54099385  4.857      11.467     ]
  [ 7.         -8.44948087  5.404      11.073     ]
  [ 8.         -8.35845922  5.595      12.356     ]
  [ 9.         -8.33891506  2.213       8.436     ]]
7-Phloroeckol-BE
7
7-Phloroeckol.7.log
[[ 1.         -9.13303038  0.          0.        ]
  [ 2.         -8.6670965   3.327       6.935     ]
  [ 3.         -8.6251615   1.807       2.586     ]
  [ 4.         -8.33583451  3.692       8.01      ]
  [ 5.         -8.22558254  2.925       3.56      ]
  [ 6.         -8.11645005  2.539       3.359     ]
  [ 7.         -8.0962971   3.272       7.159     ]
  [ 8.         -8.0926511   3.148       6.203     ]
  [ 9.         -8.08398821  1.936       2.303     ]]
7-Phloroeckol-BE
8
7-Phloroeckol.8.log
[[ 1.         -9.18235525  0.          0.        ]
  [ 2.         -8.67150999  3.414       6.913     ]
  [ 3.         -8.51768291  3.213      11.461     ]
  [ 4.         -8.46914231  3.628       6.385     ]
  [ 5.         -8.44830485  3.113      10.84      ]
  [ 6.         -8.3596531   3.637       7.896     ]
  [ 7.         -8.27598525  2.886       3.775     ]
  [ 8.         -8.26197225  1.969       3.09      ]
  [ 9.         -8.18242741  3.622       6.408     ]]
7-Phloroeckol-BE
9
7-Phloroeckol.9.log
[[ 1.         -9.29877154  0.          0.        ]
  [ 2.         -9.04913298  3.136       6.735     ]
  [ 3.         -9.0223066   2.33        9.597     ]
  [ 4.         -8.95225114  2.821       5.26      ]
  [ 5.         -8.80905279  1.812       2.432     ]
  [ 6.         -8.73525232  2.965       5.919     ]
  [ 7.         -8.62100389  2.822       5.276     ]
  [ 8.         -8.5245415   3.515       7.867     ]
  [ 9.         -8.44223426  2.803       3.531     ]]
7-Phloroeckol-BE
10
7-Phloroeckol.10.log
[[ 1.         -9.30057716  0.          0.        ]
  [ 2.         -9.25630706  0.387       2.023     ]
  [ 3.         -9.22213674  2.752       9.371     ]
  [ 4.         -8.97532518  3.228       6.707     ]
  [ 5.         -8.87955892  2.877       5.421     ]
  [ 6.         -8.616238    3.09        6.056     ]
  [ 7.         -8.44447012  3.477       7.787     ]
  [ 8.         -8.30902987  3.338      10.74      ]
  [ 9.         -8.29915536  3.162       6.544     ]]
7-Phloroeckol-BE

  and the output:

runfile('/home/comp/Apps/EMSKE/PythonSoftware/Test/SARS-CoV-2a/ExtractVinaActivity.py', 
wdir='/home/comp/Apps/EMSKE/PythonSoftware/Test/SARS-CoV-2a', 
current_namespace=True)
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
1
7-Phloroeckol.1.log
[[ 1.         -9.24815359  0.          0.        ]
  [ 2.         -8.77018617  4.382      11.138     ]
  [ 3.         -8.71121521  2.155       9.423     ]
  [ 4.         -8.69308629  5.334      11.567     ]
  [ 5.         -8.66932661  4.935      11.596     ]
  [ 6.         -8.43895798  4.145      10.894     ]
  [ 7.         -8.22467105  2.364       8.799     ]
  [ 8.         -8.20285633  4.968       9.419     ]
  [ 9.         -8.19827601  2.291       8.099     ]]
7-Phloroeckol-BE
2
7-Phloroeckol.2.log
[[ 1.         -9.17474926  0.          0.        ]
  [ 2.         -8.76125135  4.477      11.177     ]
  [ 3.         -8.62503496  2.549       9.246     ]
  [ 4.         -8.51929251  5.321      10.904     ]
  [ 5.         -8.32529487  6.085      12.541     ]
  [ 6.         -8.27908207  6.051      12.457     ]
  [ 7.         -8.23362526  5.207      11.747     ]
  [ 8.         -8.22360117  5.284      11.396     ]
  [ 9.         -8.1552274   4.603      11.329     ]]
7-Phloroeckol-BE
3
7-Phloroeckol.3.log
[[ 1.         -8.94101715  0.          0.        ]
  [ 2.         -8.14939511  1.608       2.504     ]
  [ 3.         -8.12218651  2.139       3.186     ]
  [ 4.         -7.95106339 19.754      23.455     ]
  [ 5.         -7.94903298  1.795       3.034     ]
  [ 6.         -7.87858203  2.159       2.52      ]
  [ 7.         -7.84398855  2.244       3.116     ]
  [ 8.         -7.83202941  2.66        4.225     ]
  [ 9.         -7.70585579 27.441      32.52      ]]
7-Phloroeckol-BE
4
7-Phloroeckol.4.log
[[ 1.         -9.16256247  0.          0.        ]
  [ 2.         -9.00875388 17.317      22.896     ]
  [ 3.         -8.76733608  4.486      11.171     ]
  [ 4.         -8.67364017  5.072      11.659     ]
  [ 5.         -8.52560114  4.954      11.513     ]
  [ 6.         -8.31454518  5.833      12.473     ]
  [ 7.         -8.17565187  4.665      11.309     ]
  [ 8.         -8.1713394   3.529      10.53      ]
  [ 9.         -8.14095062  2.225       9.547     ]]
7-Phloroeckol-BE
5
7-Phloroeckol.5.log
[[ 1.         -9.17411506  0.          0.        ]
  [ 2.         -8.8841462   5.333      11.643     ]
  [ 3.         -8.77081732  4.476      11.169     ]
  [ 4.         -8.62460864  2.552       9.244     ]
  [ 5.         -8.44033143  5.428      11.144     ]
  [ 6.         -8.33375966  5.844      12.486     ]
  [ 7.         -8.30255093  6.09       12.539     ]
  [ 8.         -8.15969455  4.608      11.328     ]
  [ 9.         -8.12005716  5.161      11.509     ]]
7-Phloroeckol-BE
6
7-Phloroeckol.6.log
[[ 1.         -9.21752813  0.          0.        ]
  [ 2.         -8.77520263  4.762       8.699     ]
  [ 3.         -8.68887368  4.926      11.579     ]
  [ 4.         -8.62601653  2.44        9.186     ]
  [ 5.         -8.59648372  5.352      11.044     ]
  [ 6.         -8.54099385  4.857      11.467     ]
  [ 7.         -8.44948087  5.404      11.073     ]
  [ 8.         -8.35845922  5.595      12.356     ]
  [ 9.         -8.33891506  2.213       8.436     ]]
7-Phloroeckol-BE
7
7-Phloroeckol.7.log
[[ 1.         -9.13303038  0.          0.        ]
  [ 2.         -8.6670965   3.327       6.935     ]
  [ 3.         -8.6251615   1.807       2.586     ]
  [ 4.         -8.33583451  3.692       8.01      ]
  [ 5.         -8.22558254  2.925       3.56      ]
  [ 6.         -8.11645005  2.539       3.359     ]
  [ 7.         -8.0962971   3.272       7.159     ]
  [ 8.         -8.0926511   3.148       6.203     ]
  [ 9.         -8.08398821  1.936       2.303     ]]
7-Phloroeckol-BE
8
7-Phloroeckol.8.log
[[ 1.         -9.18235525  0.          0.        ]
  [ 2.         -8.67150999  3.414       6.913     ]
  [ 3.         -8.51768291  3.213      11.461     ]
  [ 4.         -8.46914231  3.628       6.385     ]
  [ 5.         -8.44830485  3.113      10.84      ]
  [ 6.         -8.3596531   3.637       7.896     ]
  [ 7.         -8.27598525  2.886       3.775     ]
  [ 8.         -8.26197225  1.969       3.09      ]
  [ 9.         -8.18242741  3.622       6.408     ]]
7-Phloroeckol-BE
9
7-Phloroeckol.9.log
[[ 1.         -9.29877154  0.          0.        ]
  [ 2.         -9.04913298  3.136       6.735     ]
  [ 3.         -9.0223066   2.33        9.597     ]
  [ 4.         -8.95225114  2.821       5.26      ]
  [ 5.         -8.80905279  1.812       2.432     ]
  [ 6.         -8.73525232  2.965       5.919     ]
  [ 7.         -8.62100389  2.822       5.276     ]
  [ 8.         -8.5245415   3.515       7.867     ]
  [ 9.         -8.44223426  2.803       3.531     ]]
7-Phloroeckol-BE
10
7-Phloroeckol.10.log
[[ 1.         -9.30057716  0.          0.        ]
  [ 2.         -9.25630706  0.387       2.023     ]
  [ 3.         -9.22213674  2.752       9.371     ]
  [ 4.         -8.97532518  3.228       6.707     ]
  [ 5.         -8.87955892  2.877       5.421     ]
  [ 6.         -8.616238    3.09        6.056     ]
  [ 7.         -8.44447012  3.477       7.787     ]
  [ 8.         -8.30902987  3.338      10.74      ]
  [ 9.         -8.29915536  3.162       6.544     ]]
7-Phloroeckol-BE

finally, 7-Phloroeckol-BE

-9.248153586
-9.174749259
-8.941017151
-9.162562472
-9.17411506
-9.217528128
-9.133030378
-9.182355251
-9.298771543
-9.300577161

There you have it.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From s.molnar at sbcglobal.net  Wed Jan 13 16:00:12 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Wed, 13 Jan 2021 16:00:12 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io> <5FFF1F9E.5010806@sbcglobal.net>
 <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com>
Message-ID: <5FFF5F5C.9000901@sbcglobal.net>



On 01/13/2021 03:38 PM, Dennis Lee Bieber wrote:
> On Wed, 13 Jan 2021 11:28:14 -0500, "Stephen P. Molnar"
> <s.molnar at sbcglobal.net> declaimed the following:
>
> 	<SNIP>
>
> 	You have a tendency to jump around in describing things, but have yet
> to actually follow any suggestions given.
>
> 	You have been asked, at least three times, to PRINT DF and PRINT
> LIGAND! Until those have been verified, anything else is irrelevant.
>
> -=-=-=-
> #!/usr/bin/env python3
> # -*- coding: utf-8 -*-
> import pandas as pd
> import numpy as np
>
> df = pd.read_csv('ligands_3')
> print(df)
>
> for ligand in df:
> 	print(ligand)
> -=-=-=-
>
> 	Run ONLY that snippet and report with exactly what it prints.
>
>
df = pd.read_csv('ligands_3')
print(df)

for ligand in df:
     print(df)
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
      7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol


-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From alan.gauld at yahoo.co.uk  Wed Jan 13 19:23:27 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 14 Jan 2021 00:23:27 +0000
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <5FFF5F5C.9000901@sbcglobal.net>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io> <5FFF1F9E.5010806@sbcglobal.net>
 <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com> <5FFF5F5C.9000901@sbcglobal.net>
Message-ID: <rto2tv$iqd$1@ciao.gmane.io>

On 13/01/2021 21:00, Stephen P. Molnar wrote:

>> df = pd.read_csv('ligands_3')
>> print(df)
>>
>> for ligand in df:
>> 	print(ligand)
>> -=-=-=-
>>
>> 	Run ONLY that snippet and report with exactly what it prints.
>>
>>
> df = pd.read_csv('ligands_3')
> print(df)
> 
> for ligand in df:
>      print(df)

Note: Dennis asked to print ligand in the second print, not df again.


But it would hekp to label the output so we know what we areseeing:

print("DF= ", df)

and

print("Ligand = ", ligand


>       7-Phloroeckol
> 0       Aloeemodin
> 1  beta-Sitosterol
>       7-Phloroeckol
> 0       Aloeemodin
> 1  beta-Sitosterol

Because its not clear abouve what output goes with what print.
Well, actually it is here because you printed df twice....
But if you print df and ligand we need to tell them, apart.


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



From s.molnar at sbcglobal.net  Thu Jan 14 06:19:56 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Thu, 14 Jan 2021 06:19:56 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <rto2tv$iqd$1@ciao.gmane.io>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io> <5FFF1F9E.5010806@sbcglobal.net>
 <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com> <5FFF5F5C.9000901@sbcglobal.net>
 <rto2tv$iqd$1@ciao.gmane.io>
Message-ID: <600028DC.4070809@sbcglobal.net>



On 01/13/2021 07:23 PM, Alan Gauld via Tutor wrote:
> On 13/01/2021 21:00, Stephen P. Molnar wrote:
>
>>> df = pd.read_csv('ligands_3')
>>> print(df)
>>>
>>> for ligand in df:
>>> 	print(ligand)
>>> -=-=-=-
>>>
>>> 	Run ONLY that snippet and report with exactly what it prints.
>>>
>>>
>> df = pd.read_csv('ligands_3')
>> print(df)
>>
>> for ligand in df:
>>       print(df)
> Note: Dennis asked to print ligand in the second print, not df again.
>
>
> But it would hekp to label the output so we know what we areseeing:
>
> print("DF= ", df)
>
> and
>
> print("Ligand = ", ligand
>
>
>>        7-Phloroeckol
>> 0       Aloeemodin
>> 1  beta-Sitosterol
>>        7-Phloroeckol
>> 0       Aloeemodin
>> 1  beta-Sitosterol
> Because its not clear abouve what output goes with what print.
> Well, actually it is here because you printed df twice....
> But if you print df and ligand we need to tell them, apart.
>
>

Excellent suggestion.

Here is the code with the print statements:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np

df = pd.read_csv('ligands_3')
print('DF = ', df)
num = [1,2,3,4,5,6,7,8,9,10]
print('NUM = ', num)

for ligand in df:
     print('LIGAND = ', ligand)
     for i in num:
         print('I = ', i)
         name_in = "{}.{}.log".format(ligand, i)
         print('NAME_IN =', name_in)
         data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)
         print('DATA = ', data)
         name_s = ligand+'-BE'
         print('NAME_S =', name_s)
         f = open(name_s, 'a')
         f.write(str(data[0,1])+'\n')
         print('DATA[0,1] = ', data[0,1])
         f.close()

Here are the results:

DF =       7-Phloroeckol
0       Aloeemodin
1  beta-Sitosterol
NUM =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
LIGAND =  7-Phloroeckol
I =  1
NAME_IN = 7-Phloroeckol.1.log
DATA =  [[ 1.         -9.24815359  0.          0.        ]
  [ 2.         -8.77018617  4.382      11.138     ]
  [ 3.         -8.71121521  2.155       9.423     ]
  [ 4.         -8.69308629  5.334      11.567     ]
  [ 5.         -8.66932661  4.935      11.596     ]
  [ 6.         -8.43895798  4.145      10.894     ]
  [ 7.         -8.22467105  2.364       8.799     ]
  [ 8.         -8.20285633  4.968       9.419     ]
  [ 9.         -8.19827601  2.291       8.099     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.248153586
I =  2
NAME_IN = 7-Phloroeckol.2.log
DATA =  [[ 1.         -9.17474926  0.          0.        ]
  [ 2.         -8.76125135  4.477      11.177     ]
  [ 3.         -8.62503496  2.549       9.246     ]
  [ 4.         -8.51929251  5.321      10.904     ]
  [ 5.         -8.32529487  6.085      12.541     ]
  [ 6.         -8.27908207  6.051      12.457     ]
  [ 7.         -8.23362526  5.207      11.747     ]
  [ 8.         -8.22360117  5.284      11.396     ]
  [ 9.         -8.1552274   4.603      11.329     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.174749259
I =  3
NAME_IN = 7-Phloroeckol.3.log
DATA =  [[ 1.         -8.94101715  0.          0.        ]
  [ 2.         -8.14939511  1.608       2.504     ]
  [ 3.         -8.12218651  2.139       3.186     ]
  [ 4.         -7.95106339 19.754      23.455     ]
  [ 5.         -7.94903298  1.795       3.034     ]
  [ 6.         -7.87858203  2.159       2.52      ]
  [ 7.         -7.84398855  2.244       3.116     ]
  [ 8.         -7.83202941  2.66        4.225     ]
  [ 9.         -7.70585579 27.441      32.52      ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -8.941017151
I =  4
NAME_IN = 7-Phloroeckol.4.log
DATA =  [[ 1.         -9.16256247  0.          0.        ]
  [ 2.         -9.00875388 17.317      22.896     ]
  [ 3.         -8.76733608  4.486      11.171     ]
  [ 4.         -8.67364017  5.072      11.659     ]
  [ 5.         -8.52560114  4.954      11.513     ]
  [ 6.         -8.31454518  5.833      12.473     ]
  [ 7.         -8.17565187  4.665      11.309     ]
  [ 8.         -8.1713394   3.529      10.53      ]
  [ 9.         -8.14095062  2.225       9.547     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.162562472
I =  5
NAME_IN = 7-Phloroeckol.5.log
DATA =  [[ 1.         -9.17411506  0.          0.        ]
  [ 2.         -8.8841462   5.333      11.643     ]
  [ 3.         -8.77081732  4.476      11.169     ]
  [ 4.         -8.62460864  2.552       9.244     ]
  [ 5.         -8.44033143  5.428      11.144     ]
  [ 6.         -8.33375966  5.844      12.486     ]
  [ 7.         -8.30255093  6.09       12.539     ]
  [ 8.         -8.15969455  4.608      11.328     ]
  [ 9.         -8.12005716  5.161      11.509     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.17411506
I =  6
NAME_IN = 7-Phloroeckol.6.log
DATA =  [[ 1.         -9.21752813  0.          0.        ]
  [ 2.         -8.77520263  4.762       8.699     ]
  [ 3.         -8.68887368  4.926      11.579     ]
  [ 4.         -8.62601653  2.44        9.186     ]
  [ 5.         -8.59648372  5.352      11.044     ]
  [ 6.         -8.54099385  4.857      11.467     ]
  [ 7.         -8.44948087  5.404      11.073     ]
  [ 8.         -8.35845922  5.595      12.356     ]
  [ 9.         -8.33891506  2.213       8.436     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.217528128
I =  7
NAME_IN = 7-Phloroeckol.7.log
DATA =  [[ 1.         -9.13303038  0.          0.        ]
  [ 2.         -8.6670965   3.327       6.935     ]
  [ 3.         -8.6251615   1.807       2.586     ]
  [ 4.         -8.33583451  3.692       8.01      ]
  [ 5.         -8.22558254  2.925       3.56      ]
  [ 6.         -8.11645005  2.539       3.359     ]
  [ 7.         -8.0962971   3.272       7.159     ]
  [ 8.         -8.0926511   3.148       6.203     ]
  [ 9.         -8.08398821  1.936       2.303     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.133030378
I =  8
NAME_IN = 7-Phloroeckol.8.log
DATA =  [[ 1.         -9.18235525  0.          0.        ]
  [ 2.         -8.67150999  3.414       6.913     ]
  [ 3.         -8.51768291  3.213      11.461     ]
  [ 4.         -8.46914231  3.628       6.385     ]
  [ 5.         -8.44830485  3.113      10.84      ]
  [ 6.         -8.3596531   3.637       7.896     ]
  [ 7.         -8.27598525  2.886       3.775     ]
  [ 8.         -8.26197225  1.969       3.09      ]
  [ 9.         -8.18242741  3.622       6.408     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.182355251
I =  9
NAME_IN = 7-Phloroeckol.9.log
DATA =  [[ 1.         -9.29877154  0.          0.        ]
  [ 2.         -9.04913298  3.136       6.735     ]
  [ 3.         -9.0223066   2.33        9.597     ]
  [ 4.         -8.95225114  2.821       5.26      ]
  [ 5.         -8.80905279  1.812       2.432     ]
  [ 6.         -8.73525232  2.965       5.919     ]
  [ 7.         -8.62100389  2.822       5.276     ]
  [ 8.         -8.5245415   3.515       7.867     ]
  [ 9.         -8.44223426  2.803       3.531     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.298771543
I =  10
NAME_IN = 7-Phloroeckol.10.log
DATA =  [[ 1.         -9.30057716  0.          0.        ]
  [ 2.         -9.25630706  0.387       2.023     ]
  [ 3.         -9.22213674  2.752       9.371     ]
  [ 4.         -8.97532518  3.228       6.707     ]
  [ 5.         -8.87955892  2.877       5.421     ]
  [ 6.         -8.616238    3.09        6.056     ]
  [ 7.         -8.44447012  3.477       7.787     ]
  [ 8.         -8.30902987  3.338      10.74      ]
  [ 9.         -8.29915536  3.162       6.544     ]]
NAME_S = 7-Phloroeckol-BE
DATA[0,1] =  -9.300577161

The resulting, saved, file 7-Phloroeckol-BE:

-9.248153586
-9.174749259
-8.941017151
-9.162562472
-9.17411506
-9.217528128
-9.133030378
-9.182355251
-9.298771543
-9.300577161



-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From s.molnar at sbcglobal.net  Thu Jan 14 15:33:00 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Thu, 14 Jan 2021 15:33:00 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <mj610gp98hevkge7pm5gq04bkcr2r97q8e@4ax.com>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io> <5FFF1F9E.5010806@sbcglobal.net>
 <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com> <5FFF5F5C.9000901@sbcglobal.net>
 <rto2tv$iqd$1@ciao.gmane.io> <600028DC.4070809@sbcglobal.net>
 <mj610gp98hevkge7pm5gq04bkcr2r97q8e@4ax.com>
Message-ID: <6000AA7C.3030902@sbcglobal.net>



On 01/14/2021 02:35 PM, Dennis Lee Bieber wrote:
> On Thu, 14 Jan 2021 06:19:56 -0500, "Stephen P. Molnar"
> <s.molnar at sbcglobal.net> declaimed the following:
>
> 	Strange, according to my client, I did send a follow-up yesterday, but
> it seems to lost somewhere in the system. Just in case, I'll duplicate most
> of it here...
>
>> DF =       7-Phloroeckol
>> 0       Aloeemodin
>> 1  beta-Sitosterol
> 	I don't know pandas but that looks suspiciously like a tabular result
> (dataframe), where "Aloeemodin" and "beta-Sitosterol" are data items
> associated with a category (?) heading of "7-Phloroeckol". Compare that to
> the examples on
> https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html
> in which the top line has "series" labels, and the left column has row
> numbers.
>
> 		label1	[label2	...	labeln]
> row0	data1-0	[data2-0...	datan-0]
> row1	data1-1	[data2-1...	datan-1]
> ..
>
>
> 	.read_csv() is probably NOT how you want to read the input file (what
> does the raw input file contain? If it is just three lines of names, you do
> not want to be interpreting the first line as a column heading with the
> rest as data values belonging to that column).
>
>> NUM =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> LIGAND =  7-Phloroeckol
> 	While you "think" this is the first of three data items, as far as
> pandas is concerned, this is the LABEL of the first (of only one) "data
> series", and you are never accessing the data series content. And since
> there is only one data series in the frame, the loop exits.
>
>
>
Upon refection, I think that you are absolutely correct. That would 
explain why there was no incrementation. In actuality there are going to 
be quite a few more ligands, the first round that I am contemplating 
will be 298, to be exact. Now, if you consider that I initially will be 
doing ten repetitions of the docking of each ligand to seven different 
proteins that would be on the order of 20860 sets of data to be 
processed. Not a particularly unwieldy number as this sort of study is 
concerned.

The question, and my problem, then becomes how do I get a list of 
ligands into the script to extract the one number from each file?
A solution would be greatly appreciated.

Thanks in advance.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From alan.gauld at yahoo.co.uk  Thu Jan 14 16:28:03 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 14 Jan 2021 21:28:03 +0000
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <6000AA7C.3030902@sbcglobal.net>
References: <5FFDF954.2080904@sbcglobal.net>
 <X/4YL8PJUI5DPMRO@cskk.homeip.net> <5FFEF81A.2030006@sbcglobal.net>
 <rtn428$136k$1@ciao.gmane.io> <5FFF1F9E.5010806@sbcglobal.net>
 <i8muvfp0u5irvp8hjr550tcq2k3soejdq4@4ax.com> <5FFF5F5C.9000901@sbcglobal.net>
 <rto2tv$iqd$1@ciao.gmane.io> <600028DC.4070809@sbcglobal.net>
 <mj610gp98hevkge7pm5gq04bkcr2r97q8e@4ax.com> <6000AA7C.3030902@sbcglobal.net>
Message-ID: <rtqd13$14i9$1@ciao.gmane.io>

On 14/01/2021 20:33, Stephen P. Molnar wrote:

>>> NUM =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> LIGAND =  7-Phloroeckol
>> 	While you "think" this is the first of three data items, as far as
>> pandas is concerned, this is the LABEL of the first (of only one) "data
>> series", and you are never accessing the data series content. And since
>> there is only one data series in the frame, the loop exits.
>>
> Upon refection, I think that you are absolutely correct. That would 
> explain why there was no incrementation. In actuality there are going to 
> be quite a few more ligands, the first round that I am contemplating 
> will be 298, to be exact. Now, if you consider that I initially will be 
> doing ten repetitions of the docking of each ligand to seven different 
> proteins that would be on the order of 20860 sets of data to be 
> processed. Not a particularly unwieldy number as this sort of study is 
> concerned.
> 
> The question, and my problem, then becomes how do I get a list of 
> ligands into the script to extract the one number from each file?
> A solution would be greatly appreciated.

It depends on the file format but if it is just a list of ligand names
then just treat it as a refgular text file:

with open(filename) as ligand_file:
    for ligand in ligand_file:
       for num in range(1,11):
          # code as before

-- 
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  Thu Jan 14 16:30:56 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Fri, 15 Jan 2021 08:30:56 +1100
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <6000AA7C.3030902@sbcglobal.net>
References: <6000AA7C.3030902@sbcglobal.net>
Message-ID: <YAC4EBKwWO224kas@cskk.homeip.net>

On 14Jan2021 15:33, Stephen P. Molnar <s.molnar at sbcglobal.net> wrote:
>On 01/14/2021 02:35 PM, Dennis Lee Bieber wrote:
>>>DF =       7-Phloroeckol
>>>0       Aloeemodin
>>>1  beta-Sitosterol
>>	I don't know pandas but that looks suspiciously like a tabular result
>>(dataframe), where "Aloeemodin" and "beta-Sitosterol" are data items
>>associated with a category (?) heading of "7-Phloroeckol".
[...]
>Upon refection, I think that you are absolutely correct. That would 
>explain why there was no incrementation. In actuality there are going 
>to be quite a few more ligands, the first round that I am contemplating 
>will be 298, to be exact. [...]
>The question, and my problem, then becomes how do I get a list of 
>ligands into the script to extract the one number from each file?
>A solution would be greatly appreciated.

Well you've got 2 choices here. You could stick with the panda CSV stuff 
and put a heading on your CSV:

    ligand_name
    7-Phloroeckol
    Aloeemodin
    beta-Sitosterol

and process the dataframe DF as a single column dataframe.

Or you could do what my first instinct would be (since I've not had 
cause/time to use pandas) and _not_ treat the ligand file as a CSV.

    with open("ligands") as ligands_f:
        for line in ligands_f:
            ligand = line.strip()
            .... do the per-ligand stuff here ...

It's just a text file with a ligand name on each line. Open it and read 
it that way.

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

From s.molnar at sbcglobal.net  Fri Jan 15 08:24:07 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Fri, 15 Jan 2021 08:24:07 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <YAC4EBKwWO224kas@cskk.homeip.net>
References: <6000AA7C.3030902@sbcglobal.net> <YAC4EBKwWO224kas@cskk.homeip.net>
Message-ID: <60019777.7080002@sbcglobal.net>



On 01/14/2021 04:30 PM, Cameron Simpson wrote:
> On 14Jan2021 15:33, Stephen P. Molnar <s.molnar at sbcglobal.net> wrote:
>> On 01/14/2021 02:35 PM, Dennis Lee Bieber wrote:
>>>> DF =       7-Phloroeckol
>>>> 0       Aloeemodin
>>>> 1  beta-Sitosterol
>>> 	I don't know pandas but that looks suspiciously like a tabular result
>>> (dataframe), where "Aloeemodin" and "beta-Sitosterol" are data items
>>> associated with a category (?) heading of "7-Phloroeckol".
> [...]
>> Upon refection, I think that you are absolutely correct. That would
>> explain why there was no incrementation. In actuality there are going
>> to be quite a few more ligands, the first round that I am contemplating
>> will be 298, to be exact. [...]
>> The question, and my problem, then becomes how do I get a list of
>> ligands into the script to extract the one number from each file?
>> A solution would be greatly appreciated.
> Well you've got 2 choices here. You could stick with the panda CSV stuff
> and put a heading on your CSV:
>
>      ligand_name
>      7-Phloroeckol
>      Aloeemodin
>      beta-Sitosterol
>
> and process the dataframe DF as a single column dataframe.
>
> Or you could do what my first instinct would be (since I've not had
> cause/time to use pandas) and _not_ treat the ligand file as a CSV.
>
>      with open("ligands") as ligands_f:
>          for line in ligands_f:
>              ligand = line.strip()
>              .... do the per-ligand stuff here ...
>
> It's just a text file with a ligand name on each line. Open it and read
> it that way.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
So close, yet so far. I would like to think that I've learned some 
lessons so far in this thread. I',m really most appreciative of the 
assistance of the group.

I kept forgetting to mention that I am using the current Spyder in an 
cvirtual environment.

I'm going a line at a time. So far:

with open('ligands_3') as ligand_file:

for ligand in ligand_file:

for num in range(1,11):

print(ligand)

name_in = "{}.{}.log".format(ligand, num)

print('NAME_IN = ',name_in)

At this point, the script does increment all of the for statements.

In Spyder I get:

NAME_IN = 7-Phloroeckol .1.log

through

NAME_IN = beta-Sitosterol .10.log

even I can see that there is obviously a line feed lurking in the RAM. . .

the next line in the script would be:

data = np.genfromtxt(name_in,skip_header=28, skip_footer=1)

and, surprise surprise this throws an error on execution:

OSError: 7-Phloroeckol .1.log not found.


whoops! where did the line feed come from? Running dos2unix on the 
ligand file had no effect.

Well I found the line feed by running the code in a terminal.

('NAME_IN = ', '7-Phloroeckol\n.1.log')

  all the way to the end of ligands_3 (incrementing, of course.)

Now I'm really tearing out what little hair I have left - were did the 
'\n' originate??????

Sorry to be such a dunce (must be a hangover from FORTRAN II).

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From alan.gauld at yahoo.co.uk  Fri Jan 15 08:42:56 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 15 Jan 2021 13:42:56 +0000
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <60019777.7080002@sbcglobal.net>
References: <6000AA7C.3030902@sbcglobal.net>
 <YAC4EBKwWO224kas@cskk.homeip.net> <60019777.7080002@sbcglobal.net>
Message-ID: <aa9bace3-11e8-3547-768d-640e1fea9aa2@yahoo.co.uk>


On 15/01/2021 13:24, Stephen P. Molnar wrote:
>
> with open('ligands_3') as ligand_file:
>
> for ligand in ligand_file:
>
You want to add a line here:


ligand = ligand.rstrip()


That will remove the linefeed which was read from the file.

Cameron had that in his code(I forgot!)...


> Now I'm really tearing out what little hair I have left - were did the
'\n' originate??????

It was in the original ligands file - separating the lines from each other.


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


From s.molnar at sbcglobal.net  Fri Jan 15 09:16:40 2021
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Fri, 15 Jan 2021 09:16:40 -0500
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <aa9bace3-11e8-3547-768d-640e1fea9aa2@yahoo.co.uk>
References: <6000AA7C.3030902@sbcglobal.net>
 <YAC4EBKwWO224kas@cskk.homeip.net> <60019777.7080002@sbcglobal.net>
 <aa9bace3-11e8-3547-768d-640e1fea9aa2@yahoo.co.uk>
Message-ID: <6001A3C8.3010703@sbcglobal.net>



On 01/15/2021 08:42 AM, Alan Gauld via Tutor wrote:
> On 15/01/2021 13:24, Stephen P. Molnar wrote:
>> with open('ligands_3') as ligand_file:
>>
>> for ligand in ligand_file:
>>
> You want to add a line here:
>
>
> ligand = ligand.rstrip()
>
>
> That will remove the linefeed which was read from the file.
>
> Cameron had that in his code(I forgot!)...
>
>
>> Now I'm really tearing out what little hair I have left - were did the
> '\n' originate??????
>
> It was in the original ligands file - separating the lines from each other.
>
>
> --
> 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
>
Words are in adequate to express my thanks for the assistance that I 
have received in solving this problem!!!

It Works!!!!!!!!!!!!!!!!!!!!!!!!!!

MANY, MANY THANKS.

-- 
Stephen P. Molnar, Ph.D.
www.molecular-modeling.net
614.312.7528 (c)
Skype:  smolnar1


From kevand at Berksiu.org  Fri Jan 15 09:00:58 2021
From: kevand at Berksiu.org (Kevin Andreyo)
Date: Fri, 15 Jan 2021 14:00:58 +0000
Subject: [Tutor] Seeking Help for CMU CS Academy - Spinning Arcs
Message-ID: <99BAB156-7DD4-4DD3-A360-B4B678FA18B9@contoso.com>

Greetings:

I?m working through the exercises for CMU CS Academy-- a project in Carnegie Mellon University?s School of Computer Science (SCS) that has the goal of developing a novel, world-class, online, interactive high school computer science curriculum that is entirely free.
I am working on the exercise 7.4 Spinning Arcs. I understand what the startAngle and sweepAngle of an arc are. I?m just not understanding what the code means by ?updating? the start and sweep angles. I can?t seem to get my angles to change at all.

This is my code?

app.background = rgb(0, 0, 60)

arcs = Group()

for i in range(10):
    # Each green strip is an arc with the center covered by another arc.
    # The strips are drawn from big to small so the covering arcs only cover
    # the arcs that are bigger than them.
    arc1 = Arc(200, 200, 401 - (40 * i), 401 - (40 * i), 0, 10,
               fill=rgb(0, 25 * (i + 1), 20 * (i + 1)))
    arc2 = Arc(200, 200, 370 - (40 * i), 370 - (40 * i), 0, 10,
               fill=rgb(0, 0, 60))

    # dA is the change in the start angle, dS is the change in the sweep angle.
    arc1.dA = i + 1
    arc1.dS = 2 * (i + 1)
    arc2.dA = i + 1
    arc2.dS = 2 * (i + 1)

    arcs.add(arc1, arc2)

def moveArcs(arc):
    # If the sweepAngle will become too small or is bigger than or equal to 340,
    # change the direction that the sweep angle changes.
    ### Place Your Code Here ###
    for arc in arcs.children:
        if(0>arc.sweepAngle>=340):
            arc1.dS=-arc1.dS
            arc2.dS=-arc2.dS
    # Update the start and sweep angles of the arc.
    ### Place Your Code Here ###
        arc.startAngle=arc1.dA
        arc.sweepAngle=arc1.dS
    # When the start angle gets to 360, reset it to 0.
    ### Place Your Code Here ###
        if(arc.startAngle>=360):
            arc.startAngle=0

def onStep():
    for arc in arcs.children:
        moveArcs(arc)

Thank you for your help.
Sincerely,
Kevin
________________________________
IMPORTANT/CONFIDENTIAL: This communication is intended solely for the use of the individual or entity to which it is addressed. This e-mail contains information from the Berks County Intermediate Unit that may be privileged, confidential, and exempt from disclosure under applicable law. If the reader of this communication is not the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately and permanently delete this message including all attachments.
________________________________

From torresbrayan70 at gmail.com  Fri Jan 15 11:51:47 2021
From: torresbrayan70 at gmail.com (brayan torres)
Date: Fri, 15 Jan 2021 13:51:47 -0300
Subject: [Tutor] Help :c
Message-ID: <CAGVpJ=uCTBAAbQDyNF3UsaDpZfo3GdKNyGXBxB9ufxcnXNkTtw@mail.gmail.com>

Greetings:

I?m working on exercises in Python, I'm a beginner. I have a problem with
this exercise:
Book Titles

You have been asked to make a special book categorization program, which
assigns each book a special code based on its title.
The code is equal to the first letter of the book, followed by the number
of characters in the title.
For example, for the book "Harry Potter", the code would be: H12, as it
contains 12 characters (including the space).

You are provided a books.txt file, which includes the book titles, each one
written on a separate line.
Read the title one by one and output the code for each book on a separate
line.

For example, if the books.txt file contains:
Some book
Another book

Your program should output:
S9
A12
Recall the readlines() method, which returns a list containing the lines of
the file.
Also, remember that all lines, except the last one, contain a \n at the
end, which should not be included in the character count.

I understand what I should do but my output is not the same as (S9 or
A12)..

This is my code?
file = open("/usercode/files/books.txt", "r")

for i in file.readlines():
   print(i[0])
   print(len(i))

file.close()

my output is:
H
13
T
17
P
20
G
18


Thank you for your help.
Brian

From alan.gauld at yahoo.co.uk  Fri Jan 15 18:29:44 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 15 Jan 2021 23:29:44 +0000
Subject: [Tutor] Help :c
In-Reply-To: <CAGVpJ=uCTBAAbQDyNF3UsaDpZfo3GdKNyGXBxB9ufxcnXNkTtw@mail.gmail.com>
References: <CAGVpJ=uCTBAAbQDyNF3UsaDpZfo3GdKNyGXBxB9ufxcnXNkTtw@mail.gmail.com>
Message-ID: <rtt8h8$842$1@ciao.gmane.io>

On 15/01/2021 16:51, brayan torres wrote:
> Recall the readlines() method, which returns a list containing the lines of
> the file.

You don't need that advice its nearly always better just
to loop over the file object.

> Also, remember that all lines, except the last one, contain a \n at the
> end, which should not be included in the character count.

You seem to have ignored that bit of advice!

> I understand what I should do but my output is not the same as (S9 or
> A12)..

The S9 and A12 only apply to the 2 line example, not
to your actual data. But remember the advice about \n
above otherwise you will have the wrong results.

> This is my code?
> file = open("/usercode/files/books.txt", "r")
> 
> for i in file.readlines():

ignoring readlines() would give you

for line in file:

Which is preferred because you don't read the whole
file into memory at once. Faster and more memory
efficient.

Does the name line seem more like the thing you are
reading than i? Choosing useful names makes code much
easier to work with.

>    print(i[0])
>    print(len(i))

> my output is:
> H
> 13
> T
> 17

You need to print out more than just the letter and the length,
you need to combine them into a single string.
There are several ways to do that, probably the simplest
is string addition.


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



From alan.gauld at yahoo.co.uk  Fri Jan 15 18:41:21 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 15 Jan 2021 23:41:21 +0000
Subject: [Tutor] Seeking Help for CMU CS Academy - Spinning Arcs
In-Reply-To: <99BAB156-7DD4-4DD3-A360-B4B678FA18B9@contoso.com>
References: <99BAB156-7DD4-4DD3-A360-B4B678FA18B9@contoso.com>
Message-ID: <rtt972$gr4$1@ciao.gmane.io>

On 15/01/2021 14:00, Kevin Andreyo via Tutor wrote:

> ...just not understanding what the code means by ?updating? > the start and sweep angles. I can?t seem to get my angles
> to change at all.


> This is my code?
> 
> app.background = rgb(0, 0, 60)
> arcs = Group()
> 
> for i in range(10):
>     arc1 = Arc(200, 200, ...
>     arc2 = Arc(200, 200, ...
>     ...
>     arcs.add(arc1, arc2)

In the above code you create a group and add arc pairs.
Then your program stops.

In the code below you define two functions but
neither is ever called. So they do nothing.

> def moveArcs(arc):
>     ### Place Your Code Here ###
>     for arc in arcs.children:
>         if(0>arc.sweepAngle>=340):
>             arc1.dS=-arc1.dS
>             arc2.dS=-arc2.dS
>     # Update the start and sweep angles of the arc.
>     ### Place Your Code Here ###
>         arc.startAngle=arc1.dA
>         arc.sweepAngle=arc1.dS
>     # When the start angle gets to 360, reset it to 0.
>     ### Place Your Code Here ###
>         if(arc.startAngle>=360):
>             arc.startAngle=0
> 
> def onStep():
>     for arc in arcs.children:
>         moveArcs(arc)

So how is onStep ever called?
Remember we are not doing your course and have no idea
how this framework operates. You need to guide us.
Its not clear if some piece of code swe cannot see
is calling onstep or whether you are supposed to call
it explicitly - BUt how? From where?

One thing that does seeem odd to me is that onStep loops over
arcs.children and calls moveArcs.
But the first thing movearcs does is loop over arcs.children?
So effectively you code does this:

for arc1 in arcs.children:
     for arc2 in arcs.children:
         # do stuff

Is that right?

The other thing I notice is that you pass the current
arc into moveArcs as 'arc' But you also use arc in
the loop which means you immediately throw away the
value passed into the function and replace it with
the for loop value. That is almost certainly wrong.

I can't say much more because the code and descriptions
are not complete enough to make any sense of things.

-- 
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 Jan 15 19:48:30 2021
From: pytutor at danceswithmice.info (dn)
Date: Sat, 16 Jan 2021 13:48:30 +1300
Subject: [Tutor] Why Doesn't the for loop Increment?
In-Reply-To: <60019777.7080002@sbcglobal.net>
References: <6000AA7C.3030902@sbcglobal.net>
 <YAC4EBKwWO224kas@cskk.homeip.net> <60019777.7080002@sbcglobal.net>
Message-ID: <78282218-6b8e-e6b3-5e49-73a9a7952633@DancesWithMice.info>

On 16/01/2021 02.24, Stephen P. Molnar wrote:
...

> Now I'm really tearing out what little hair I have left - were did the
> '\n' originate??????
> 
> Sorry to be such a dunce (must be a hangover from FORTRAN II).


Exactly!
(the FORTRAN bit, not the "dunce")


Traditionally languages, and certainly FORTRAN-II/-IV, accepted input as
fixed-length records, ie each read/input instruction expected the same
number of characters. (think of punched-cards and their 80-characters -
whether all 80 were utilised, or not)

Whereas Python (typically) uses "streams". That is to say, a file is
thought-of as a stream of characters (cf a series of records).

In this format, the first 'record' may contain two characters and the
next twenty. (stream-files do not use the term "record", but we are used
to it, so will continue to do so - if only for the length of this
conversation!)

However, the idea of a "stream" (of characters) raises the question: how
are two consecutive 'records' separated/how do we know where each begins
and ends? Thus, the term: "separator".

NB Sadly, the particular separator used in particular situations may not
be the same on all machines/Operating Systems. eg in pathnames
MS-Windows uses "\" whereas the rest of the world uses "/"; and although
some use a newline 'character' to indicate the ends of 'records' in
files, others use 'carriage return', or indeed a combination of
'carriage return, line-feed'. Sigh!

You will find this discussed in the Python documentation, eg os library,
read() and input(), etc - important to research because some include the
separator and some "strip" it from 'the data', and Python's input() may
'behave' differently from some other library's input() 'equivalent
function'!
(thus @Alan's suggestion to use str.strip() to remove those pesky
'superfluous' "\n" ("New line") characters!)


Although not part of your question, in the case of print(), there is a
"sep" parameter and another for "end". The latter enabling override of
the system-default. Now you can see why! (if not, you will next...)


The former ("sep") brings us neatly to the concepts of CSV-files (comma
separated variables), whose very name features the word "separated", if
not "separator" (the character/symbol which achieves the "separation").
The "comma" separates one field within a record from its successor. You
may have come-across a variant which uses the tab-key/-character instead
(technically/precisely called a TSV-file). Both names ignoring the point
made above, that there is *also* a need to define a separator to
separate 'records'!

Before long, such flexibility induces one to part-quote Sir Walter Scott
(English-English literature) "oh what a tangled web we weave"!
(apologies, I've been having way to much fun with word-games this
morning...)


You can see the value of earlier contributor's advice: that
input/processed values be carefully-checked to ensure that they are
exactly what is required - no more, no less! Remember the old adage:
"GIGO" (garbage in, garbage out)!
(and complementing the recommended research, above)


As a further update/improvement to your coding: Have you come-across TDD
(Test-driven Development)? If not, with a brief investigation, it will
likely recommend itself, in part because of its parallels with 'the
Scientific Method', ie hypothesise then (dis)prove (+).

Thus, in logic we might say: if we have a and b as inputs, function-f
will produce output-c - alternately: if we need output-c from inputs-a
and -b, function-f must transform by ...

In Python-code, we can say:

    assert f( a, b ) == c

If execution of f() works correctly, such a test is deemed 'successful'
because the assert will yield True, and execution continues. If the
function produces a result other than the (expected) value-c, then the
assert[ion] yields False, and we conclude that there is either something
wrong with the data, or with the function!

So, from such a basis TDD says: write the test/assertion first. (*).
Then write f()'s code. Then run the test (cf running the function
directly), to 'prove' the code. If the test fails, consider the error -
which one assumes will require a code-change/correction. 'Rinse and
repeat', until the test 'passes'.

(* some put a 'test run' at this point, but without any function-f it
must surely fail/the result is a foregone conclusion, so this lazy-boy
wonders: why bother?)

Note that these tests which one writes should be kept separate from what
will eventually be the delivered 'production code'. However, they are
not one-off routines to be discarded upon delivery! Should the code be
augmented in future, the tests will be very useful to ensure that these
'new changes' don't 'damage' the existing code/fail to meet the original
objectives!

These are termed "unit tests", because we decompose the
overall-problem/hypothesis, into smaller problems, until we arrive at an
easily solvable/soluble, smaller, unit of code. If we test each unit,
then we have the basis of an expectation that the entirety will work.
More importantly, we are some way towards a "proof".

Obviously, you will want more than one test, both for a single unit and
because the whole-program(me) consists of multiple "units"; so a 'test
runner' eg PyTest; is a very handy tool and can usually be employed as
an add-in to one's IDE (apologies: I can't comment on Spyder).
Test-runners have the advantage of running every test, even if one
'fails' (which an assert statement, on its own, will not). The IDE can
usually be set to run the tests every time you save the file, and
CVS/DevOps systems (should you use such) can require the test-suite be
run before any code is delivered to users...


In summary, using Python after FORTRAN looks much the same, yet offers
many exciting 'new'/extra opportunities - but it also requires us
'silver surfers' to update some of the philosophies and "semantics"
within our coding practice and that are particular/pertinent to this
programming language.

Accordingly, in addition to the previously-mentioned Python
research/reading/learning, may I recommend these two higher-thought
ideas to you:
1 stepwise decomposition/modular programming - to assist your
'translation' of real-world needs into (Python) code.
2 TDD - to identify short-comings in the solution (and/or your
understanding of Python) at the lowest-possible level/earliest-possible
juncture - ensuring that each module of code contributes correctly
towards the wider, desired solution.
-- 
Regards =dn

From mhysnm1964 at gmail.com  Sun Jan 24 01:45:29 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Sun, 24 Jan 2021 17:45:29 +1100
Subject: [Tutor] storing and saving file tree structure
Message-ID: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>

All,

 

I have a directory for all the books I own. In this directory I have
organised as follows:

 

D:\authors\a\Anne rice\title\filename.pdf

 

Title - is the title of the book and the filename could be a PDF, Mob, MP3,
ETC. depending where I have purchased the book. What I am trying to do is
bring all the information into a spreadsheet. Hence why I am trying to bring
in the whole directory structure into a data struct like a dict.

 

Considerations:

*	Some directories have multiple files. Thus when you use pathlib you
will get multiple path objects. For example:
D:\authors\a\Anne rice\title\track1.mp3
D:\authors\a\Anne rice\title\track2.mp3
D:\authors\a\Anne rice\title\track3.mp3

*	I do not want the filenames to be included, only the directory names
which I have worked out.
*	The last directory is normally the title of the book. This is how I
have structured the directory.
*	I want to remove duplicate entries of author names and titles.
*	Want to import into Excel - I have information on this part. Either
directly into a spreadsheet or use CSV.

I think that is about it for the considerations. What I cannot work out is
how to write the code to remove duplicates. Dictionaries are really great to
identify duplicate keys because you can use a simple if test. Finding
duplicates in a list is more challenging. The structure I am using is:

 

Books = {"Anne Rice": []} # dict with a list.

 

Only methods I have found to identify duplicates within lists is using for
loops. Thus I was trying to work out how to use dictionaries instead and
could not. Creating nested dictionaries dynamically is beyond my ability.

 

Below is the code an I am hoping someone can give me some pointers.

 

 

import  re, csv

from pathlib import Path

 

def csv_export (data):

    # dumps the data list to a csv and has to be an list

    with open ('my-books.csv', 'w', newline="") as fp:

        writer = csv.writer(fp)

        writer.writerows(data)

# end def  

 

books = {}

bookPath = []

dirList = Path(r"e:\authors") # starting directory

for path in dirList.rglob('*'): # loading the whole directory structure.

    if not path.is_dir(): # Checks to see if is a file.

        bookPath = list(path.relative_to(dirList).parts) # extracts the file
path as a tuple without "e:\author".

        bookPath.pop() # removes the file from the path parts, as we only
want directory names.

       author = bookPath[1] # author name is always the 2nd element.

        if author in books: # check for existing keys

            if  bookPath[-1] not in books[author]: # trying to find
duplicate titles but fails. 

                books[author].append(bookPath)

            # end if 

        else: # creates new entries for dict.

            books[author] = bookPath

        # end if 

    # end if 

# end for

 

I suspect I might have to do recursive functions but not sure how to do
this. I always have challenges with recursive logic. I hope someone can help
and the above makes sense.

 

Sean

 

 


From tyriqhowll at gmail.com  Sat Jan 23 22:52:15 2021
From: tyriqhowll at gmail.com (Tyriq Howell)
Date: Sat, 23 Jan 2021 22:52:15 -0500
Subject: [Tutor] Dictionary
Message-ID: <8F53DA52-C05E-4AB9-AA37-5469DCA29A8C@gmail.com>

I was wondering how do I get the dictionary by using sys.argv and then looping it to sort it from ascending order and then from descending order 

Sent from my iPhone

From alan.gauld at yahoo.co.uk  Sun Jan 24 04:27:37 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 24 Jan 2021 09:27:37 +0000
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>
References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>
Message-ID: <rujei9$f4l$1@ciao.gmane.io>

On 24/01/2021 06:45, mhysnm1964 at gmail.com wrote:

> D:\authors\a\Anne rice\title\filename.pdf
> 
> Title - is the title of the book and the filename could be a PDF, Mob, MP3,
> ETC. depending where I have purchased the book. What I am trying to do is
> bring all the information into a spreadsheet. Hence why I am trying to bring
> in the whole directory structure into a data struct like a dict.

You could use a database instead.
SQLite comes with python and can be run in memory rather than on disk.

> *	Some directories have multiple files. Thus when you use pathlib you
> will get multiple path objects. For example:
> D:\authors\a\Anne rice\title\track1.mp3
> D:\authors\a\Anne rice\title\track2.mp3
> D:\authors\a\Anne rice\title\track3.mp3
> 
> *	I do not want the filenames to be included, only the directory names
> which I have worked out.
> *	The last directory is normally the title of the book. This is how I
> have structured the directory.
> *	I want to remove duplicate entries of author names and titles.
> *	Want to import into Excel - I have information on this part. Either
> directly into a spreadsheet or use CSV.

Rewording the requirement.

You have a set of authors and each author has a set of books associated.
Is that it?

> how to write the code to remove duplicates. Dictionaries are really great to
> identify duplicate keys because you can use a simple if test. Finding
> duplicates in a list is more challenging. 

So don't use a list. use a set. sets remove duplicates automatically
(ie they don't allow them to exist!)

> Books = {"Anne Rice": []} # dict with a list.

Books = {"Anne Rice": set()} # dict with a set

> Only methods I have found to identify duplicates within lists is using for
> loops. Thus I was trying to work out how to use dictionaries instead and
> could not. Creating nested dictionaries dynamically is beyond my ability.

Its really not difficult. Lets pretent you wanted all the files
associated woth each book:

Books = {"Anne rice": {"Book Title": [list,of,files]}}

Personally I use formatting to show the layout better if I'm building
it statically, but in your case you are loading it dynamically from
your files.

Books = {
         "Anne rice": {
                       "Book1": [
                                list,
                                of,
                                files
                                ],
                       "Book2": [
                                More,
                                Files
                                ]
                       },
         "Next author": {
                         etc...
                 }
        }

But since you don;t need that just use a set instead of a list.

> import  re, csv
> 
> from pathlib import Path

> def csv_export (data):
>     # dumps the data list to a csv and has to be an list

You can write a dict to a CSV and the dict keys become
the column headings. Look at the Dictwriter.

>     with open ('my-books.csv', 'w', newline="") as fp:
>         writer = csv.writer(fp)
>         writer.writerows(data)
> # end def  
> 
> books = {}
> bookPath = []
> dirList = Path(r"e:\authors") # starting directory
> 
> for path in dirList.rglob('*'): # loading the whole directory structure.
> 
>     if not path.is_dir(): # Checks to see if is a file.
> 
>         bookPath = list(path.relative_to(dirList).parts) # extracts the file
> path as a tuple without "e:\author".
> 
>         bookPath.pop() # removes the file from the path parts, as we only
> want directory names.
> 
>        author = bookPath[1] # author name is always the 2nd element.
> 
>         if author in books: # check for existing keys

Its a dictionary why do you care? Just add the books to the author
entry, if it exists it will work, if it doesn't the entry will be created.

> 
>             if  bookPath[-1] not in books[author]: # trying to find
> duplicate titles but fails.

If you use a set you don;t need to check. but...
In what way fails? It should succeed with an in test even
if its not very efficient.
>                 books[author].append(bookPath)
>             # end if 
>         else: # creates new entries for dict.
>             books[author] = bookPath
>         # end if 
>     # end if 
> # end for

One of the reasons Python uses indentation is to avoid all these
end markers and their misleading, and thus bug-forming, implications.
It's rather ironic that you are putting them back in as comments! :)

> I suspect I might have to do recursive functions but not sure how to do
> this. I always have challenges with recursive logic. I hope someone can help
> and the above makes sense.

It looks like it should work, although you only check the books if the
author is already there. Where is the code to handle the case where its
a new author?

But if you use a dict of sets you avoids all of that checking business.

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



From alan.gauld at yahoo.co.uk  Sun Jan 24 04:36:11 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 24 Jan 2021 09:36:11 +0000
Subject: [Tutor] Dictionary
In-Reply-To: <8F53DA52-C05E-4AB9-AA37-5469DCA29A8C@gmail.com>
References: <8F53DA52-C05E-4AB9-AA37-5469DCA29A8C@gmail.com>
Message-ID: <rujf2b$b1k$1@ciao.gmane.io>

On 24/01/2021 03:52, Tyriq Howell wrote:
> I was wondering how do I get the dictionary by using sys.argv 
> and then looping it to sort it from ascending order and then from descending order 

This sounds like a homework and we won;t do your homework for you.

But we can offer suggestions, answer questions, review code etc.

My first question to you is how would the dict data be passed
in using argv? (This is a very unusual way of working with
dicts BTW!)

Can you show us an example of how the program would be called
and what the resulting dictionary would look like?

The second point I'd make is you really have 2 separate issues.

1) How to construct a dict from argv - which depends on the
   answer to my question above.

and

2) how to "sort" a dictionary.

Sorting a dictionary isn't normally very helpful because you
can extract the data directly in any order you choose. But
you can sort it's keys into some order. I think in recent
python versions the built-in sorted() function works with
dictionaries try it out on some sample data and see how it
works. Then read the documentation for how to control
its sort order. If that's not clear enough come back
here and ask away.

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



From CitizenQuasar at protonmail.com  Sun Jan 24 19:14:15 2021
From: CitizenQuasar at protonmail.com (Dan)
Date: Mon, 25 Jan 2021 00:14:15 +0000
Subject: [Tutor] Fw: PLEASE HELP!
In-Reply-To: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@protonmail.com>
References: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@protonmail.com>
Message-ID: <ntURWjxZ7-wbOv7H70LufUYTVXfexa5gEpAYHYY7CTwUHoI7nUgiewjaXbUhuXIYGtLDH4wyyJpCUC2Gpr0yTEqtJfWwNjaHPsScFA1o_Bg=@protonmail.com>

Lines join in faint discord and the Stormwatch brews a concert of kings as the white sea snaps at the heels of a soft prayer whispered.

Sent with [ProtonMail](https://protonmail.com) Secure Email.

??????? Original Message ???????
On Sunday, January 24, 2021 5:13 PM, Dan <CitizenQuasar at protonmail.com> wrote:

> TO WHOM IT MAY CONCERN:
>
> I am trying to download and install a python matrix module. I am using python 3.8.7 and running it on Windows 7. So far, all I have been doing for days is clicking on links that go around and around without telling me how to download Matrix. If anyone will send me an email telling me how to download and install Matrix then I will greatly appreciate it. Otherwise, I am through with Python as it impossible for me to use.
>
> Lines join in faint discord and the Stormwatch brews a concert of kings as the white sea snaps at the heels of a soft prayer whispered.
>
> Sent with [ProtonMail](https://protonmail.com) Secure Email.

From alan.gauld at yahoo.co.uk  Sun Jan 24 20:22:05 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 25 Jan 2021 01:22:05 +0000
Subject: [Tutor] Fw: PLEASE HELP!
In-Reply-To: <ntURWjxZ7-wbOv7H70LufUYTVXfexa5gEpAYHYY7CTwUHoI7nUgiewjaXbUhuXIYGtLDH4wyyJpCUC2Gpr0yTEqtJfWwNjaHPsScFA1o_Bg=@protonmail.com>
References: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@protonmail.com>
 <ntURWjxZ7-wbOv7H70LufUYTVXfexa5gEpAYHYY7CTwUHoI7nUgiewjaXbUhuXIYGtLDH4wyyJpCUC2Gpr0yTEqtJfWwNjaHPsScFA1o_Bg=@protonmail.com>
Message-ID: <rul6ft$4ok$1@ciao.gmane.io>

On 25/01/2021 00:14, Dan via Tutor wrote:

>> I am trying to download and install a python matrix module.

There are several. Which one?

Most folks use numpy, but that's a lot more than a matrix
module its a whole raft of math type goodies.

>  I am using python 3.8.7 and running it on Windows 7. 


> So far, all I have been doing for days is clicking 
> on links that go around and around without telling 
> me how to download Matrix. 

Most python modules these days are installed using
the pip command. That should both download and install it.
But unless you tell us exactly which module you are trying
to install we can't be more specific.

> Otherwise, I am through with Python as it impossible for me to use.

That's OK too, there are lots of other programming languages to choose.
But they mostly all have similar issues when you try to install non
standard libraries.

-- 
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 Jan 24 20:32:14 2021
From: PyTutor at DancesWithMice.info (dn)
Date: Mon, 25 Jan 2021 14:32:14 +1300
Subject: [Tutor] Fw: PLEASE HELP!
In-Reply-To: <ntURWjxZ7-wbOv7H70LufUYTVXfexa5gEpAYHYY7CTwUHoI7nUgiewjaXbUhuXIYGtLDH4wyyJpCUC2Gpr0yTEqtJfWwNjaHPsScFA1o_Bg=@protonmail.com>
References: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@protonmail.com>
 <ntURWjxZ7-wbOv7H70LufUYTVXfexa5gEpAYHYY7CTwUHoI7nUgiewjaXbUhuXIYGtLDH4wyyJpCUC2Gpr0yTEqtJfWwNjaHPsScFA1o_Bg=@protonmail.com>
Message-ID: <2afe8516-eda8-4cc4-c5f5-9d594b09b5c0@DancesWithMice.info>

On 25/01/2021 13.14, Dan via Tutor wrote:
...
>> I am trying to download and install a python matrix module. I am using python 3.8.7 and running it on Windows 7. So far, all I have been doing for days is clicking on links that go around and around without telling me how to download Matrix. If anyone will send me an email telling me how to download and install Matrix then I will greatly appreciate it. Otherwise, I am through with Python as it impossible for me to use.
...

Welcome to this mailing list = volunteers helping each other.


Which links have you been trying?

Which Matrix module?


The largest formal collection of Python libraries is PyPi, aka 'the
Cheese Shop'. It has an entry for "matrix 2.0.1", which was last updated
back in 2017 and is described as a "Generic matrix generator". Is that
what you're wanting?
(https://pypi.org/project/matrix/)

Using pip to install from PyPi is a standard Python operation, albeit
with several variants. Are you competent, or lacking familiarity with
the technique?


Suggestions:
1 a meaningful Subject line which will help others scanning the list's
archives, who might have the same problem in-future
2 ridding messages of repetitive and non-Python material (as per above
'gardening')
3 avoid transferring personal frustration - as if we, your colleagues,
will only respond to 'blackmail' or 'guilt-trips'
-- 
Regards =dn

From mhysnm1964 at gmail.com  Mon Jan 25 04:20:40 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Mon, 25 Jan 2021 20:20:40 +1100
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <rujei9$f4l$1@ciao.gmane.io>
References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>
 <rujei9$f4l$1@ciao.gmane.io>
Message-ID: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>

Allan,

As indents are a visual formatting structure. It is difficult for a screen
reader user like myself to keep the blocks of code correctly indented. Thus
why I am using the comments at the end of the code.

I will have to recheck my logic for the dict's, as I got errors in the past.
I will check out sets as that sounds useful. 

I have found some other code using os.walk which I am checking out.

Yes, I could use a database to store all this information which I might do
later. Learning the language and creation of datasets with a goal in mind to
achieve what I need for a short term solution.

Thanks for the tips. I will go and have a investigation.

Sean 

-----Original Message-----
From: Tutor <tutor-bounces+mhysnm1964=gmail.com at python.org> On Behalf Of
Alan Gauld via Tutor
Sent: Sunday, 24 January 2021 8:28 PM
To: tutor at python.org
Subject: Re: [Tutor] storing and saving file tree structure

On 24/01/2021 06:45, mhysnm1964 at gmail.com wrote:

> D:\authors\a\Anne rice\title\filename.pdf
> 
> Title - is the title of the book and the filename could be a PDF, Mob, 
> MP3, ETC. depending where I have purchased the book. What I am trying 
> to do is bring all the information into a spreadsheet. Hence why I am 
> trying to bring in the whole directory structure into a data struct like a
dict.

You could use a database instead.
SQLite comes with python and can be run in memory rather than on disk.

> *	Some directories have multiple files. Thus when you use pathlib you
> will get multiple path objects. For example:
> D:\authors\a\Anne rice\title\track1.mp3 D:\authors\a\Anne 
> rice\title\track2.mp3 D:\authors\a\Anne rice\title\track3.mp3
> 
> *	I do not want the filenames to be included, only the directory names
> which I have worked out.
> *	The last directory is normally the title of the book. This is how I
> have structured the directory.
> *	I want to remove duplicate entries of author names and titles.
> *	Want to import into Excel - I have information on this part. Either
> directly into a spreadsheet or use CSV.

Rewording the requirement.

You have a set of authors and each author has a set of books associated.
Is that it?

> how to write the code to remove duplicates. Dictionaries are really 
> great to identify duplicate keys because you can use a simple if test. 
> Finding duplicates in a list is more challenging.

So don't use a list. use a set. sets remove duplicates automatically (ie
they don't allow them to exist!)

> Books = {"Anne Rice": []} # dict with a list.

Books = {"Anne Rice": set()} # dict with a set

> Only methods I have found to identify duplicates within lists is using 
> for loops. Thus I was trying to work out how to use dictionaries 
> instead and could not. Creating nested dictionaries dynamically is beyond
my ability.

Its really not difficult. Lets pretent you wanted all the files associated
woth each book:

Books = {"Anne rice": {"Book Title": [list,of,files]}}

Personally I use formatting to show the layout better if I'm building it
statically, but in your case you are loading it dynamically from your files.

Books = {
         "Anne rice": {
                       "Book1": [
                                list,
                                of,
                                files
                                ],
                       "Book2": [
                                More,
                                Files
                                ]
                       },
         "Next author": {
                         etc...
                 }
        }

But since you don;t need that just use a set instead of a list.

> import  re, csv
> 
> from pathlib import Path

> def csv_export (data):
>     # dumps the data list to a csv and has to be an list

You can write a dict to a CSV and the dict keys become the column headings.
Look at the Dictwriter.

>     with open ('my-books.csv', 'w', newline="") as fp:
>         writer = csv.writer(fp)
>         writer.writerows(data)
> # end def
> 
> books = {}
> bookPath = []
> dirList = Path(r"e:\authors") # starting directory
> 
> for path in dirList.rglob('*'): # loading the whole directory structure.
> 
>     if not path.is_dir(): # Checks to see if is a file.
> 
>         bookPath = list(path.relative_to(dirList).parts) # extracts 
> the file path as a tuple without "e:\author".
> 
>         bookPath.pop() # removes the file from the path parts, as we 
> only want directory names.
> 
>        author = bookPath[1] # author name is always the 2nd element.
> 
>         if author in books: # check for existing keys

Its a dictionary why do you care? Just add the books to the author entry, if
it exists it will work, if it doesn't the entry will be created.

> 
>             if  bookPath[-1] not in books[author]: # trying to find 
> duplicate titles but fails.

If you use a set you don;t need to check. but...
In what way fails? It should succeed with an in test even if its not very
efficient.
>                 books[author].append(bookPath)
>             # end if 
>         else: # creates new entries for dict.
>             books[author] = bookPath
>         # end if 
>     # end if
> # end for

One of the reasons Python uses indentation is to avoid all these end markers
and their misleading, and thus bug-forming, implications.
It's rather ironic that you are putting them back in as comments! :)

> I suspect I might have to do recursive functions but not sure how to 
> do this. I always have challenges with recursive logic. I hope someone 
> can help and the above makes sense.

It looks like it should work, although you only check the books if the
author is already there. Where is the code to handle the case where its a
new author?

But if you use a dict of sets you avoids all of that checking business.

--
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 leitman375 at yahoo.com  Mon Jan 25 14:45:56 2021
From: leitman375 at yahoo.com (Nirel Leitman)
Date: Mon, 25 Jan 2021 19:45:56 +0000 (UTC)
Subject: [Tutor] Pygame Help
References: <430038133.3206314.1611603956089.ref@mail.yahoo.com>
Message-ID: <430038133.3206314.1611603956089@mail.yahoo.com>


Hello,


I am getting an error stating that there is no module named 'pygame'.? Here is the screen shot of that error:
Python 3.9.1 (tags/v3.9.1:1e5d33e, Dec? 7 2020, 17:08:21) [MSC v.1927 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license()" for more information.>>> import pygameTraceback (most recent call last):? File "<pyshell#0>", line 1, in <module>? ? import pygameModuleNotFoundError: No module named 'pygame'
I am using Windows 10 and I have tried to install Pygame but for some reason my computer isn't seeing it.? I downloaded Pygame from?Downloads (pygame.org)

| 
| 
|  | 
Downloads


 |

 |

 |

?where I downloaded the newest version which is 1.9.6 Package.

? Any suggestions?

Thank you.


From leitman375 at yahoo.com  Mon Jan 25 15:24:41 2021
From: leitman375 at yahoo.com (Nirel Leitman)
Date: Mon, 25 Jan 2021 20:24:41 +0000 (UTC)
Subject: [Tutor] Python Error Message
References: <931371355.3654533.1611606281365.ref@mail.yahoo.com>
Message-ID: <931371355.3654533.1611606281365@mail.yahoo.com>

I keep getting this error message:
C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py "C:\Users\leitm\Desktop\AI\degrees.py\small"C:\Users\leitm\AppData\Local\Programs\Python\Python39\python.exe: can't find '__main__' module in 'C:\\Users\\leitm\\Desktop\\AI\\degrees.py'?Why can't my computer find my folder?? What do I need to change for my computer to read this?
Thank you,Nirel Leitman

From alan.gauld at yahoo.co.uk  Mon Jan 25 19:55:06 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Jan 2021 00:55:06 +0000
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>
 <rujei9$f4l$1@ciao.gmane.io> <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
Message-ID: <runp9a$1f5$1@ciao.gmane.io>

On 25/01/2021 09:20, mhysnm1964 at gmail.com wrote:

> As indents are a visual formatting structure. It is difficult for a screen
> reader user like myself to keep the blocks of code correctly indented. Thus
> why I am using the comments at the end of the code.

Ah, that makes sense. You just need to bear in mind the traps
that they introduce of prematurely ending blocks and
inadvertently chopping blocks into pieces.

> I will check out sets as that sounds useful. 

OK, Also don;t forget the setdefault() method of dicts which is what
saves you from having to check for membership...

books.setdefault(anAuthor, set()).add(book)

Will always work because setdefault() returns the existing
set for an existing key and adds (and returns) a new empty
set for a non-existent key.

-- 
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 Jan 25 20:04:06 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Jan 2021 01:04:06 +0000
Subject: [Tutor] Python Error Message
In-Reply-To: <931371355.3654533.1611606281365@mail.yahoo.com>
References: <931371355.3654533.1611606281365.ref@mail.yahoo.com>
 <931371355.3654533.1611606281365@mail.yahoo.com>
Message-ID: <runpq6$17dm$1@ciao.gmane.io>

On 25/01/2021 20:24, Nirel Leitman via Tutor wrote:
> I keep getting this error message:
> C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py "C:\Users\leitm\Desktop\AI\degrees.py\small"> C:\Users\leitm\AppData\Local\Programs\Python\Python39\python.exe:

The error says:
> can't find '__main__' module in 'C:\\Users\\leitm\\Desktop\\AI\\degrees.py' 

> Why can't my computer find my folder?

It evidently can, it is a main module that it says is missing not
that it can't find the file. It's looking in the file for main
and not finding it.

> ? What do I need to change for my computer to read this?

It depends on what is in the file.
Can you show us the main code for degrees.py?


-- 
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 Jan 25 19:59:58 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Jan 2021 00:59:58 +0000
Subject: [Tutor] Pygame Help
In-Reply-To: <430038133.3206314.1611603956089@mail.yahoo.com>
References: <430038133.3206314.1611603956089.ref@mail.yahoo.com>
 <430038133.3206314.1611603956089@mail.yahoo.com>
Message-ID: <runpie$msu$1@ciao.gmane.io>

On 25/01/2021 19:45, Nirel Leitman via Tutor wrote:

> I am getting an error stating that there is no module named 'pygame'.? 

> downloaded Pygame from?Downloads (pygame.org)

I don't know how you did that, I couldn't find a downloads
section on the web site!

> ?where I downloaded the newest version which is 1.9.6 Package.

Pygame 2.0 was released at the end of October 2020.

And the recommended way to install it is with pip:
The following line is provided on the web site:

python3 -m pip install pygame==2.0.0

Try that and see you it goes.

-- 
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  Mon Jan 25 20:46:09 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 26 Jan 2021 12:46:09 +1100
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
References: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
Message-ID: <YA90YZpRVspl2Ktf@cskk.homeip.net>

On 25Jan2021 20:20, Sean Murphy <mhysnm1964 at gmail.com> wrote:
>As indents are a visual formatting structure. It is difficult for a 
>screen reader user like myself to keep the blocks of code correctly indented. Thus
>why I am using the comments at the end of the code.

Ah.

Speaking with some ignorance here, is it useful to you to indent using 
tab characters instead of spaces, if you are using spaces? Can your 
screen reader be asked to pronouns tabs differently? You would only need 
one tab per indent.

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

From jf_byrnes at comcast.net  Mon Jan 25 21:21:10 2021
From: jf_byrnes at comcast.net (Jim Byrnes)
Date: Mon, 25 Jan 2021 20:21:10 -0600
Subject: [Tutor] Rerouting a traceback
Message-ID: <runuan$d14$1@ciao.gmane.io>

Linux Mint 20 - Python 3.8

Is it possible to reroute a traceback to a GUI wintow?

Here's why I ask. I usually run scripts using a launcher app on my top 
panel.  The scripts download stock data and then manipulate it in 
Libreoffice calc. The execution time varies. After a while if nothing 
appears in calc I assume there was an error and must re-launch the 
script from a terminal to see what went wrong.

It would be helpful if I could display the error when it occurs in popup 
window.

I've googled it but so far haven't found any help. I've used pysimplegui 
on occasion and thought maybe it's debug window would do the trick but 
so far I haven't been able to figure anything out.

So before I waste anymore time on this I would like to know if it is 
possible and maybe a hint on how to do it if it is possible.

Thanks,  Jim



From mats at wichmann.us  Mon Jan 25 22:15:02 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 25 Jan 2021 20:15:02 -0700
Subject: [Tutor] Rerouting a traceback
In-Reply-To: <runuan$d14$1@ciao.gmane.io>
References: <runuan$d14$1@ciao.gmane.io>
Message-ID: <9342f02f-f44e-cd37-b1ff-00da040b5fbe@wichmann.us>


On 1/25/21 7:21 PM, Jim Byrnes wrote:
> Linux Mint 20 - Python 3.8
> 
> Is it possible to reroute a traceback to a GUI wintow?

It's software, so it's possible...

> 
> Here's why I ask. I usually run scripts using a launcher app on my top 
> panel.? The scripts download stock data and then manipulate it in 
> Libreoffice calc. The execution time varies. After a while if nothing 
> appears in calc I assume there was an error and must re-launch the 
> script from a terminal to see what went wrong.
> 
> It would be helpful if I could display the error when it occurs in popup 
> window.
> 
> I've googled it but so far haven't found any help. I've used pysimplegui 
> on occasion and thought maybe it's debug window would do the trick but 
> so far I haven't been able to figure anything out.
> 
> So before I waste anymore time on this I would like to know if it is 
> possible and maybe a hint on how to do it if it is possible.

If the script you launch is your own - that is, if you feel like 
modifying it - it can just pop up a simple message box. This might end 
up being sufficient:

from tkinter import messagebox

messagebox.showerror("FAILED", "error message from the failure")


but you'll need to ampliy what you need and who controls what in this 
scenario, it might be more complicated.

From mhysnm1964 at gmail.com  Mon Jan 25 23:09:19 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Tue, 26 Jan 2021 15:09:19 +1100
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <YA90YZpRVspl2Ktf@cskk.homeip.net>
References: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
 <YA90YZpRVspl2Ktf@cskk.homeip.net>
Message-ID: <003f01d6f399$06f69ee0$14e3dca0$@gmail.com>

Cameron

Thanks for asking. It all depends on the editor. Notepad++ does both. I just
find it easier to identify the block ends this way. Very non-conforming I
know.

I also found a recipe on how to achieve what I want by using OS.Walk. 

import os, functools, ftplib 

def get_directory_structure(rootdir):
    """
    Creates a nested dictionary that represents the folder structure of
rootdir
    """
    dir = {}
    rootdir = rootdir.rstrip(os.sep)
    start = rootdir.rfind(os.sep) + 1
    for path, dirs, files in os.walk(rootdir):
        if len(dirs) > 0:
            folders = path[start:].split(os.sep)
            subdir = dict.fromkeys(dirs)
            parent = functools.reduce(dict.get, folders[:-1], dir)
            parent[folders[-1]] = subdir
    return dir


#load local books into title dict.
titles = get_directory_structure(r'e:\authors')

If I remove the if test in the function. Then I can create a directory
structure with all the files.  This is a good example of using os.walk.


Sean 

-----Original Message-----
From: Cameron Simpson <cs at cskk.id.au> 
Sent: Tuesday, 26 January 2021 12:46 PM
To: mhysnm1964 at gmail.com
Cc: 'Alan Gauld' <alan.gauld at yahoo.co.uk>; tutor at python.org
Subject: Re: [Tutor] storing and saving file tree structure

On 25Jan2021 20:20, Sean Murphy <mhysnm1964 at gmail.com> wrote:
>As indents are a visual formatting structure. It is difficult for a 
>screen reader user like myself to keep the blocks of code correctly 
>indented. Thus why I am using the comments at the end of the code.

Ah.

Speaking with some ignorance here, is it useful to you to indent using tab
characters instead of spaces, if you are using spaces? Can your screen
reader be asked to pronouns tabs differently? You would only need one tab
per indent.

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


From mhysnm1964 at gmail.com  Mon Jan 25 23:21:33 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Tue, 26 Jan 2021 15:21:33 +1100
Subject: [Tutor] storing and saving file tree structure
In-Reply-To: <runp9a$1f5$1@ciao.gmane.io>
References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com>
 <rujei9$f4l$1@ciao.gmane.io> <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com>
 <runp9a$1f5$1@ciao.gmane.io>
Message-ID: <047d01d6f39a$bc6c5de0$354519a0$@gmail.com>

Allan and Cameron,

I did send this to Cameron previously and forgot to add the group on to the
mail.

Thanks for the interest in the screen reader. It depends on the editor if
the right indent information is provided. Notepad++ seems to be okay. But it
is my default way of work.

I did find a solution which I will share below (excuse if the formatting
does not work):


import os, functools, ftplib

def get_directory_structure(rootdir):
    """
    Creates a nested dictionary that represents the folder structure of
rootdir
    """
    dir = {}
    rootdir = rootdir.rstrip(os.sep)
    start = rootdir.rfind(os.sep) + 1
    for path, dirs, files in os.walk(rootdir):
        if len(dirs) > 0:
            folders = path[start:].split(os.sep)
            subdir = dict.fromkeys(dirs)
            parent = functools.reduce(dict.get, folders[:-1], dir)
            parent[folders[-1]] = subdir
    return dir

#load local books into title dict.
titles = get_directory_structure(r'e:\authors')

This did exactly what I wanted. Thanks for the information on sets. I will
save this as a excellent tip.

Sean 
-----Original Message-----
From: Tutor <tutor-bounces+mhysnm1964=gmail.com at python.org> On Behalf Of
Alan Gauld via Tutor
Sent: Tuesday, 26 January 2021 11:55 AM
To: tutor at python.org
Subject: Re: [Tutor] storing and saving file tree structure

On 25/01/2021 09:20, mhysnm1964 at gmail.com wrote:

> As indents are a visual formatting structure. It is difficult for a 
> screen reader user like myself to keep the blocks of code correctly 
> indented. Thus why I am using the comments at the end of the code.

Ah, that makes sense. You just need to bear in mind the traps that they
introduce of prematurely ending blocks and inadvertently chopping blocks
into pieces.

> I will check out sets as that sounds useful. 

OK, Also don;t forget the setdefault() method of dicts which is what saves
you from having to check for membership...

books.setdefault(anAuthor, set()).add(book)

Will always work because setdefault() returns the existing set for an
existing key and adds (and returns) a new empty set for a non-existent key.

--
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 mhysnm1964 at gmail.com  Mon Jan 25 23:28:37 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Tue, 26 Jan 2021 15:28:37 +1100
Subject: [Tutor] using ftp within Python and walking the directory tree.
Message-ID: <048a01d6f39b$b96f5510$2c4dff30$@gmail.com>

All.

 

Using Python 3.8 I have been successful in connecting to my own ftp server
by using ftplib. I found a tool called ftptool which does installed with my
version of python (3.8). But when using:

Import ftptool

 

There is a dependency called module six which it cannot find, thus it does
not load. As this is a very old package. I am seeking for a ftp package or
code examples that can act like os.walk. I found the following article which
references the above module.

 

https://hongsupshin.com/2017/02/19/connect-python-and-ftp-server/

 

 

Does anyone know of a package that works with Python 3.8 which permits you
to walk an FTP directory?

 

Sean 

 

 


From __peter__ at web.de  Tue Jan 26 03:38:25 2021
From: __peter__ at web.de (Peter Otten)
Date: Tue, 26 Jan 2021 09:38:25 +0100
Subject: [Tutor] using ftp within Python and walking the directory tree.
In-Reply-To: <048a01d6f39b$b96f5510$2c4dff30$@gmail.com>
References: <048a01d6f39b$b96f5510$2c4dff30$@gmail.com>
Message-ID: <ecfe79ab-3e85-a326-7b4c-b1986756287c@web.de>

On 26/01/2021 05:28, mhysnm1964 at gmail.com wrote:

> Using Python 3.8 I have been successful in connecting to my own ftp server
> by using ftplib. I found a tool called ftptool which does installed with my
> version of python (3.8). But when using:
>
> Import ftptool
>
>
>
> There is a dependency called module six which it cannot find, thus it does
> not load.

six is a compatibility layer to allow writing programs that run on
python 2 and 3. You can find it here:

https://pypi.org/project/six/

On Linux install it with

sudo pip3 install six

if the package manager doesn't provide a package.

On Windows use

py -m pip install six

in the Powershell.

From __peter__ at web.de  Tue Jan 26 03:38:25 2021
From: __peter__ at web.de (Peter Otten)
Date: Tue, 26 Jan 2021 09:38:25 +0100
Subject: [Tutor] using ftp within Python and walking the directory tree.
In-Reply-To: <048a01d6f39b$b96f5510$2c4dff30$@gmail.com>
References: <048a01d6f39b$b96f5510$2c4dff30$@gmail.com>
Message-ID: <ecfe79ab-3e85-a326-7b4c-b1986756287c@web.de>

On 26/01/2021 05:28, mhysnm1964 at gmail.com wrote:

> Using Python 3.8 I have been successful in connecting to my own ftp server
> by using ftplib. I found a tool called ftptool which does installed with my
> version of python (3.8). But when using:
> 
> Import ftptool
> 
>   
> 
> There is a dependency called module six which it cannot find, thus it does
> not load. 

six is a compatibility layer to allow writing programs that run on 
python 2 and 3. You can find it here:

https://pypi.org/project/six/

On Linux install it with

sudo pip3 install six

if the package manager doesn't provide a package.

On Windows use

py -m pip install six

in the Powershell.


From sk12356790 at gmail.com  Mon Jan 25 23:49:24 2021
From: sk12356790 at gmail.com (H K)
Date: Tue, 26 Jan 2021 13:49:24 +0900
Subject: [Tutor] Why do I get "None"?
Message-ID: <CAAncBHVr16PpNbd3AtgzjBaJ8GByGRLa_wm1NmwkRMqO3xz4mg@mail.gmail.com>

def greeting_2(name):
    print("Hello " + name)

example = greeting_2("Christine")
print(example)

This gives the value:
Hello Christine
None

And I don't understand why I'm getting "None"

From alan.gauld at yahoo.co.uk  Tue Jan 26 04:23:43 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Jan 2021 09:23:43 +0000
Subject: [Tutor] Why do I get "None"?
In-Reply-To: <CAAncBHVr16PpNbd3AtgzjBaJ8GByGRLa_wm1NmwkRMqO3xz4mg@mail.gmail.com>
References: <CAAncBHVr16PpNbd3AtgzjBaJ8GByGRLa_wm1NmwkRMqO3xz4mg@mail.gmail.com>
Message-ID: <ruon2v$3a0$1@ciao.gmane.io>

On 26/01/2021 04:49, H K wrote:
> def greeting_2(name):
>     print("Hello " + name)

Every time you define a function without an explicit return
statement Python implicitly returns None.

> example = greeting_2("Christine")

The line above prints he greeting inside the function

> print(example)

This line prints the return value which is None.

> This gives the value:
> Hello Christine

>From inside the function

> None

>From your print(example)

This confusion could have been avoided by *returning*
the greeting as a string rather than printing it inside
the function:

def greeting_3(name):
    return "Hello" + name

example = greeting_3("Christine")
print(example)

This is considered better practice than embedding
print statements inside functions that create data.
Generate the data inside the function and return it.
Then print the result of the function separately.


-- 
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  Tue Jan 26 04:42:00 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 26 Jan 2021 09:42:00 +0000
Subject: [Tutor] Rerouting a traceback
In-Reply-To: <runuan$d14$1@ciao.gmane.io>
References: <runuan$d14$1@ciao.gmane.io>
Message-ID: <ruoo58$76t$1@ciao.gmane.io>

On 26/01/2021 02:21, Jim Byrnes wrote:
> Linux Mint 20 - Python 3.8
> 
> Is it possible to reroute a traceback to a GUI wintow?
> 
> Here's why I ask. I usually run scripts using a launcher app on my top 
> panel.  


The simplest way is put the launcher into a bash shell.
redirect stderr into a /tmp/file. If the file exists at the
end of execution launch (or if it contains an error string?)
launch your favourite GUI editor on the file.

It is a fairly trivial bash script and exactly the
kind of thing that bash scripts are intended for..

Something like:

#! /bin/bash
python3 myscript.py any args here 2> /tmp/myscript_errors
[ -e /tmp/myscript_errors] && xedit /tmp/myscript_errors &

-- 
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  Tue Jan 26 20:42:06 2021
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 27 Jan 2021 01:42:06 +0000
Subject: [Tutor] Python Error Message
In-Reply-To: <1521051109.210743.1611681481476@mail.yahoo.com>
References: <931371355.3654533.1611606281365.ref@mail.yahoo.com>
 <931371355.3654533.1611606281365@mail.yahoo.com>
 <runpq6$17dm$1@ciao.gmane.io>
 <1521051109.210743.1611681481476@mail.yahoo.com>
Message-ID: <2e52cc1e-0670-99fa-a18f-5b2a87b906b0@btinternet.com>


On 26/01/2021 17:18, Nirel Leitman wrote:
> Here is the main code for degrees.py -- it is very long:
>
> import?csv
> import?sys
> from?util?import?Node,?StackFrontier,?QueueFrontier
> #?Maps?names?to?a?set?of?corresponding?person_ids
> names?=?{}
> #?Maps?person_ids?to?a?dictionary?of:?name,?birth,?movies?(a?set?of?movie_ids)
> people?=?{}
> #?Maps?movie_ids?to?a?dictionary?of:?title,?year,?stars?(a?set?of?person_ids)
> movies?=?{}
> def?load_data(directory):
> ????"""
> ????Load?data?from?CSV?files?into?memory.
> ????"""
> ????#?Load?people
> ????with?open(f"{directory}/people.csv",?encoding="utf-8")?as?f:
> ????????reader?=?csv.DictReader(f)
> ????????for?row?in?reader:
> ????????????people[row["id"]]?=?{
> ????????????????"name":?row["name"],
> ????????????????"birth":?row["birth"],
> ????????????????"movies":?set()
> ????????????}
> ????????????if?row["name"].lower()?not?in?names:
> ????????????????names[row["name"].lower()]?=?{row["id"]}
> ????????????else:
> ????????????????names[row["name"].lower()].add(row["id"])
> ????#?Load?movies
> ????with?open(f"{directory}/movies.csv",?encoding="utf-8")?as?f:
> ????????reader?=?csv.DictReader(f)
> ????????for?row?in?reader:
> ????????????movies[row["id"]]?=?{
> ????????????????"title":?row["title"],
> ????????????????"year":?row["year"],
> ????????????????"stars":?set()
> ????????????}
> ????#?Load?stars
> ????with?open(f"{directory}/stars.csv",?encoding="utf-8")?as?f:
> ????????reader?=?csv.DictReader(f)
> ????????for?row?in?reader:
> ????????????try:
> ????????????????people[row["person_id"]]["movies"].add(row["movie_id"])
> ????????????????movies[row["movie_id"]]["stars"].add(row["person_id"])
> ????????????except?KeyError:
> ????????????????pass
> def?main():
> ????if?len(sys.argv)?>?2:
> ????????sys.exit("Usage:?python?degrees.py?[directory]")
> ????directory?=?sys.argv[1]?if?len(sys.argv)?==?2?else?"large"
> ????#?Load?data?from?files?into?memory
> ????print("Loading?data...")
> ????load_data(directory)
> ????print("Data?loaded.")
> ????source?=?person_id_for_name(input("Name:?"))
> ????if?source?is?None:
> ????????sys.exit("Person?not?found.")
> ????target?=?person_id_for_name(input("Name:?"))
> ????if?target?is?None:
> ????????sys.exit("Person?not?found.")
> ????path?=?shortest_path(source,?target)
> ????if?path?is?None:
> ????????print("Not?connected.")
> ????else:
> ????????degrees?=?len(path)
> ????????print(f"{degrees}?degrees?of?separation.")
> ????????path?=?[(None,?source)]?+?path
> ????????for?i?in?range(degrees):
> ????????????person1?=?people[path[i][1]]["name"]
> ????????????person2?=?people[path[i?+?1][1]]["name"]
> ????????????movie?=?movies[path[i?+?1][0]]["title"]
> ????????????print(f"{i?+?1}:?{person1}?and?{person2}?starred?in?{movie}")
> def?shortest_path(source,?target):
> ????"""
> ????Returns?the?shortest?list?of?(movie_id,?person_id)?pairs
> ????that?connect?the?source?to?the?target.
> ????If?no?possible?path,?returns?None.
> ????"""
> ????#?TODO
> ????raise?NotImplementedError
> def?person_id_for_name(name):
> ????"""
> ????Returns?the?IMDB?id?for?a?person's?name,
> ????resolving?ambiguities?as?needed.
> ????"""
> ????person_ids?=?list(names.get(name.lower(),?set()))
> ????if?len(person_ids)?==?0:
> ????????return?None
> ????elif?len(person_ids)?>?1:
> ????????print(f"Which?'{name}'?")
> ????????for?person_id?in?person_ids:
> ????????????person?=?people[person_id]
> ????????????name?=?person["name"]
> ????????????birth?=?person["birth"]
> ????????????print(f"ID:?{person_id},?Name:?{name},?Birth:?{birth}")
> ????????try:
> ????????????person_id?=?input("Intended?Person?ID:?")
> ????????????if?person_id?in?person_ids:
> ????????????????return?person_id
> ????????except?ValueError:
> ????????????pass
> ????????return?None
> ????else:
> ????????return?person_ids[0]
> def?neighbors_for_person(person_id):
> ????"""
> ????Returns?(movie_id,?person_id)?pairs?for?people
> ????who?starred?with?a?given?person.
> ????"""
> ????movie_ids?=?people[person_id]["movies"]
> ????neighbors?=?set()
> ????for?movie_id?in?movie_ids:
> ????????for?person_id?in?movies[movie_id]["stars"]:
> ????????????neighbors.add((movie_id,?person_id))
> ????return?neighbors
> if?__name__?==?"__main__":
> ????main()
>
> Please let me know how I can proceed from here.? Thank you again for
> your assistance.
>
> - Nirel
>
> On Monday, January 25, 2021, 06:04:41 PM MST, Alan Gauld via Tutor
> <tutor at python.org> wrote:
>
>
> On 25/01/2021 20:24, Nirel Leitman via Tutor wrote:
> > I keep getting this error message:
> > C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py
> "C:\Users\leitm\Desktop\AI\degrees.py\small">
> C:\Users\leitm\AppData\Local\Programs\Python\Python39\python.exe:
>
> The error says:
> > can't find '__main__' module in
> 'C:\\Users\\leitm\\Desktop\\AI\\degrees.py'
>
> > Why can't my computer find my folder?
>
> It evidently can, it is a main module that it says is missing not
> that it can't find the file. It's looking in the file for main
> and not finding it.
>
> > ? What do I need to change for my computer to read this?
>
> It depends on what is in the file.
> Can you show us the main code for degrees.py?
>
>
> -- 
> 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

-- 
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  Tue Jan 26 20:47:39 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 27 Jan 2021 01:47:39 +0000
Subject: [Tutor] Python Error Message
In-Reply-To: <2e52cc1e-0670-99fa-a18f-5b2a87b906b0@btinternet.com>
References: <931371355.3654533.1611606281365.ref@mail.yahoo.com>
 <931371355.3654533.1611606281365@mail.yahoo.com>
 <runpq6$17dm$1@ciao.gmane.io>
 <1521051109.210743.1611681481476@mail.yahoo.com>
 <2e52cc1e-0670-99fa-a18f-5b2a87b906b0@btinternet.com>
Message-ID: <ruqgnr$veu$1@ciao.gmane.io>

I'm forwarding to the list so others can comment....


I've loaded and run your file and (once I mock up unit.py_)
it works with no errors until it tries to load data.
So I'm not seeing the error you are getting which suggests
its an environment issue.

However, looking back at your original post I noticed
something odd that I missed first time:

C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py
"C:\Users\leitm\Desktop\AI\degrees.py\small"

The argument to degrees.py is a path string.

But the last element of the path is a filename followed
by \small - is that correct?

Your code is looking for a directory!

I don't think that would cause the missing main module
error but you should probably fix it!

The other issue there is that I'm not sure how windows
python will handle that path string with the backslashes.
You may need to escape them or use forward slashes(which
Windows can process with no problems inside a string)

Alan G.





On 27/01/2021 01:42, Alan Gauld via Tutor wrote:
> 
> On 26/01/2021 17:18, Nirel Leitman wrote:
>> Here is the main code for degrees.py -- it is very long:
>>
>> import?csv
>> import?sys
>> from?util?import?Node,?StackFrontier,?QueueFrontier
>> #?Maps?names?to?a?set?of?corresponding?person_ids
>> names?=?{}
>> #?Maps?person_ids?to?a?dictionary?of:?name,?birth,?movies?(a?set?of?movie_ids)
>> people?=?{}
>> #?Maps?movie_ids?to?a?dictionary?of:?title,?year,?stars?(a?set?of?person_ids)
>> movies?=?{}
>> def?load_data(directory):
>> ????"""
>> ????Load?data?from?CSV?files?into?memory.
>> ????"""
>> ????#?Load?people
>> ????with?open(f"{directory}/people.csv",?encoding="utf-8")?as?f:
>> ????????reader?=?csv.DictReader(f)
>> ????????for?row?in?reader:
>> ????????????people[row["id"]]?=?{
>> ????????????????"name":?row["name"],
>> ????????????????"birth":?row["birth"],
>> ????????????????"movies":?set()
>> ????????????}
>> ????????????if?row["name"].lower()?not?in?names:
>> ????????????????names[row["name"].lower()]?=?{row["id"]}
>> ????????????else:
>> ????????????????names[row["name"].lower()].add(row["id"])
>> ????#?Load?movies
>> ????with?open(f"{directory}/movies.csv",?encoding="utf-8")?as?f:
>> ????????reader?=?csv.DictReader(f)
>> ????????for?row?in?reader:
>> ????????????movies[row["id"]]?=?{
>> ????????????????"title":?row["title"],
>> ????????????????"year":?row["year"],
>> ????????????????"stars":?set()
>> ????????????}
>> ????#?Load?stars
>> ????with?open(f"{directory}/stars.csv",?encoding="utf-8")?as?f:
>> ????????reader?=?csv.DictReader(f)
>> ????????for?row?in?reader:
>> ????????????try:
>> ????????????????people[row["person_id"]]["movies"].add(row["movie_id"])
>> ????????????????movies[row["movie_id"]]["stars"].add(row["person_id"])
>> ????????????except?KeyError:
>> ????????????????pass
>> def?main():
>> ????if?len(sys.argv)?>?2:
>> ????????sys.exit("Usage:?python?degrees.py?[directory]")
>> ????directory?=?sys.argv[1]?if?len(sys.argv)?==?2?else?"large"
>> ????#?Load?data?from?files?into?memory
>> ????print("Loading?data...")
>> ????load_data(directory)
>> ????print("Data?loaded.")
>> ????source?=?person_id_for_name(input("Name:?"))
>> ????if?source?is?None:
>> ????????sys.exit("Person?not?found.")
>> ????target?=?person_id_for_name(input("Name:?"))
>> ????if?target?is?None:
>> ????????sys.exit("Person?not?found.")
>> ????path?=?shortest_path(source,?target)
>> ????if?path?is?None:
>> ????????print("Not?connected.")
>> ????else:
>> ????????degrees?=?len(path)
>> ????????print(f"{degrees}?degrees?of?separation.")
>> ????????path?=?[(None,?source)]?+?path
>> ????????for?i?in?range(degrees):
>> ????????????person1?=?people[path[i][1]]["name"]
>> ????????????person2?=?people[path[i?+?1][1]]["name"]
>> ????????????movie?=?movies[path[i?+?1][0]]["title"]
>> ????????????print(f"{i?+?1}:?{person1}?and?{person2}?starred?in?{movie}")
>> def?shortest_path(source,?target):
>> ????"""
>> ????Returns?the?shortest?list?of?(movie_id,?person_id)?pairs
>> ????that?connect?the?source?to?the?target.
>> ????If?no?possible?path,?returns?None.
>> ????"""
>> ????#?TODO
>> ????raise?NotImplementedError
>> def?person_id_for_name(name):
>> ????"""
>> ????Returns?the?IMDB?id?for?a?person's?name,
>> ????resolving?ambiguities?as?needed.
>> ????"""
>> ????person_ids?=?list(names.get(name.lower(),?set()))
>> ????if?len(person_ids)?==?0:
>> ????????return?None
>> ????elif?len(person_ids)?>?1:
>> ????????print(f"Which?'{name}'?")
>> ????????for?person_id?in?person_ids:
>> ????????????person?=?people[person_id]
>> ????????????name?=?person["name"]
>> ????????????birth?=?person["birth"]
>> ????????????print(f"ID:?{person_id},?Name:?{name},?Birth:?{birth}")
>> ????????try:
>> ????????????person_id?=?input("Intended?Person?ID:?")
>> ????????????if?person_id?in?person_ids:
>> ????????????????return?person_id
>> ????????except?ValueError:
>> ????????????pass
>> ????????return?None
>> ????else:
>> ????????return?person_ids[0]
>> def?neighbors_for_person(person_id):
>> ????"""
>> ????Returns?(movie_id,?person_id)?pairs?for?people
>> ????who?starred?with?a?given?person.
>> ????"""
>> ????movie_ids?=?people[person_id]["movies"]
>> ????neighbors?=?set()
>> ????for?movie_id?in?movie_ids:
>> ????????for?person_id?in?movies[movie_id]["stars"]:
>> ????????????neighbors.add((movie_id,?person_id))
>> ????return?neighbors
>> if?__name__?==?"__main__":
>> ????main()
>>
>> Please let me know how I can proceed from here.? Thank you again for
>> your assistance.
>>
>> - Nirel
>>
>> On Monday, January 25, 2021, 06:04:41 PM MST, Alan Gauld via Tutor
>> <tutor at python.org> wrote:
>>
>>
>> On 25/01/2021 20:24, Nirel Leitman via Tutor wrote:
>>> I keep getting this error message:
>>> C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py
>> "C:\Users\leitm\Desktop\AI\degrees.py\small">
>> C:\Users\leitm\AppData\Local\Programs\Python\Python39\python.exe:
>>
>> The error says:
>>> can't find '__main__' module in
>> 'C:\\Users\\leitm\\Desktop\\AI\\degrees.py'
>>
>>> Why can't my computer find my folder?
>>
>> It evidently can, it is a main module that it says is missing not
>> that it can't find the file. It's looking in the file for main
>> and not finding it.
>>
>>> ? What do I need to change for my computer to read this?
>>
>> It depends on what is in the file.
>> Can you show us the main code for degrees.py?
>>
>>
>> -- 
>> 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
> 


-- 
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 leitman375 at yahoo.com  Tue Jan 26 22:36:58 2021
From: leitman375 at yahoo.com (Nirel Leitman)
Date: Tue, 26 Jan 2021 19:36:58 -0800
Subject: [Tutor] Python Error Message
In-Reply-To: <ruqgnr$veu$1@ciao.gmane.io>
References: <ruqgnr$veu$1@ciao.gmane.io>
Message-ID: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com>

Thank you.  And yes, degrees.py is also a folder name along with small.  I was told that file names should have .py at the end of it so that Python can recognize it.  

I went ahead and changed the folder back to just degrees before receiving this email.  I will try again tomorrow with the forward slashing to see if that helps at all.  Also, how to do I create a directory for the small folder?

Thank you again.

> On Jan 26, 2021, at 5:48 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> 
> ?I'm forwarding to the list so others can comment....
> 
> 
> I've loaded and run your file and (once I mock up unit.py_)
> it works with no errors until it tries to load data.
> So I'm not seeing the error you are getting which suggests
> its an environment issue.
> 
> However, looking back at your original post I noticed
> something odd that I missed first time:
> 
> C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py
> "C:\Users\leitm\Desktop\AI\degrees.py\small"
> 
> The argument to degrees.py is a path string.
> 
> But the last element of the path is a filename followed
> by \small - is that correct?
> 
> Your code is looking for a directory!
> 
> I don't think that would cause the missing main module
> error but you should probably fix it!
> 
> The other issue there is that I'm not sure how windows
> python will handle that path string with the backslashes.
> You may need to escape them or use forward slashes(which
> Windows can process with no problems inside a string)
> 
> Alan G.
> 
> 
> 
> 
> 
>> On 27/01/2021 01:42, Alan Gauld via Tutor wrote:
>> 
>>> On 26/01/2021 17:18, Nirel Leitman wrote:
>>> Here is the main code for degrees.py -- it is very long:
>>> 
>>> import csv
>>> import sys
>>> from util import Node, StackFrontier, QueueFrontier
>>> # Maps names to a set of corresponding person_ids
>>> names = {}
>>> # Maps person_ids to a dictionary of: name, birth, movies (a set of movie_ids)
>>> people = {}
>>> # Maps movie_ids to a dictionary of: title, year, stars (a set of person_ids)
>>> movies = {}
>>> def load_data(directory):
>>>     """
>>>     Load data from CSV files into memory.
>>>     """
>>>     # Load people
>>>     with open(f"{directory}/people.csv", encoding="utf-8") as f:
>>>         reader = csv.DictReader(f)
>>>         for row in reader:
>>>             people[row["id"]] = {
>>>                 "name": row["name"],
>>>                 "birth": row["birth"],
>>>                 "movies": set()
>>>             }
>>>             if row["name"].lower() not in names:
>>>                 names[row["name"].lower()] = {row["id"]}
>>>             else:
>>>                 names[row["name"].lower()].add(row["id"])
>>>     # Load movies
>>>     with open(f"{directory}/movies.csv", encoding="utf-8") as f:
>>>         reader = csv.DictReader(f)
>>>         for row in reader:
>>>             movies[row["id"]] = {
>>>                 "title": row["title"],
>>>                 "year": row["year"],
>>>                 "stars": set()
>>>             }
>>>     # Load stars
>>>     with open(f"{directory}/stars.csv", encoding="utf-8") as f:
>>>         reader = csv.DictReader(f)
>>>         for row in reader:
>>>             try:
>>>                 people[row["person_id"]]["movies"].add(row["movie_id"])
>>>                 movies[row["movie_id"]]["stars"].add(row["person_id"])
>>>             except KeyError:
>>>                 pass
>>> def main():
>>>     if len(sys.argv) > 2:
>>>         sys.exit("Usage: python degrees.py [directory]")
>>>     directory = sys.argv[1] if len(sys.argv) == 2 else "large"
>>>     # Load data from files into memory
>>>     print("Loading data...")
>>>     load_data(directory)
>>>     print("Data loaded.")
>>>     source = person_id_for_name(input("Name: "))
>>>     if source is None:
>>>         sys.exit("Person not found.")
>>>     target = person_id_for_name(input("Name: "))
>>>     if target is None:
>>>         sys.exit("Person not found.")
>>>     path = shortest_path(source, target)
>>>     if path is None:
>>>         print("Not connected.")
>>>     else:
>>>         degrees = len(path)
>>>         print(f"{degrees} degrees of separation.")
>>>         path = [(None, source)] + path
>>>         for i in range(degrees):
>>>             person1 = people[path[i][1]]["name"]
>>>             person2 = people[path[i + 1][1]]["name"]
>>>             movie = movies[path[i + 1][0]]["title"]
>>>             print(f"{i + 1}: {person1} and {person2} starred in {movie}")
>>> def shortest_path(source, target):
>>>     """
>>>     Returns the shortest list of (movie_id, person_id) pairs
>>>     that connect the source to the target.
>>>     If no possible path, returns None.
>>>     """
>>>     # TODO
>>>     raise NotImplementedError
>>> def person_id_for_name(name):
>>>     """
>>>     Returns the IMDB id for a person's name,
>>>     resolving ambiguities as needed.
>>>     """
>>>     person_ids = list(names.get(name.lower(), set()))
>>>     if len(person_ids) == 0:
>>>         return None
>>>     elif len(person_ids) > 1:
>>>         print(f"Which '{name}'?")
>>>         for person_id in person_ids:
>>>             person = people[person_id]
>>>             name = person["name"]
>>>             birth = person["birth"]
>>>             print(f"ID: {person_id}, Name: {name}, Birth: {birth}")
>>>         try:
>>>             person_id = input("Intended Person ID: ")
>>>             if person_id in person_ids:
>>>                 return person_id
>>>         except ValueError:
>>>             pass
>>>         return None
>>>     else:
>>>         return person_ids[0]
>>> def neighbors_for_person(person_id):
>>>     """
>>>     Returns (movie_id, person_id) pairs for people
>>>     who starred with a given person.
>>>     """
>>>     movie_ids = people[person_id]["movies"]
>>>     neighbors = set()
>>>     for movie_id in movie_ids:
>>>         for person_id in movies[movie_id]["stars"]:
>>>             neighbors.add((movie_id, person_id))
>>>     return neighbors
>>> if __name__ == "__main__":
>>>     main()
>>> 
>>> Please let me know how I can proceed from here.  Thank you again for
>>> your assistance.
>>> 
>>> - Nirel
>>> 
>>> On Monday, January 25, 2021, 06:04:41 PM MST, Alan Gauld via Tutor
>>> <tutor at python.org> wrote:
>>> 
>>> 
>>> On 25/01/2021 20:24, Nirel Leitman via Tutor wrote:
>>>> I keep getting this error message:
>>>> C:\Users\leitm>python C:\Users\leitm\Desktop\AI\degrees.py
>>> "C:\Users\leitm\Desktop\AI\degrees.py\small">
>>> C:\Users\leitm\AppData\Local\Programs\Python\Python39\python.exe:
>>> 
>>> The error says:
>>>> can't find '__main__' module in
>>> 'C:\\Users\\leitm\\Desktop\\AI\\degrees.py'
>>> 
>>>> Why can't my computer find my folder?
>>> 
>>> It evidently can, it is a main module that it says is missing not
>>> that it can't find the file. It's looking in the file for main
>>> and not finding it.
>>> 
>>>>   What do I need to change for my computer to read this?
>>> 
>>> It depends on what is in the file.
>>> Can you show us the main code for degrees.py?
>>> 
>>> 
>>> -- 
>>> 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
>> 
> 
> 
> -- 
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


From alan.gauld at yahoo.co.uk  Wed Jan 27 04:07:11 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 27 Jan 2021 09:07:11 +0000
Subject: [Tutor] Python Error Message
In-Reply-To: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com>
References: <ruqgnr$veu$1@ciao.gmane.io>
 <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com>
Message-ID: <rurag0$118$1@ciao.gmane.io>

On 27/01/2021 03:36, Nirel Leitman via Tutor wrote:
> Thank you.  And yes, degrees.py is also a folder name along with small. 

In that case you are trying to get Python to execute a folder, which
won't work.

>  I was told that file names should have .py at the end of it so 
> that Python can recognize it.

Its so that the OS can recognize it as a python file and call
python when you double click on it. Python is happy to execute
the file even without the .py. But it is only files,
not folders, that need the .py extension.

So you need to rename your folder to degrees.
Then inside the degrees folder you need to store your
degrees.py file.
You also need to create another folder inside degrees
called small. I'm not sure what you store in small,
presumably some kind of data file?

Also given your code defaults to large there should
also be a folder called large with another(bigger?)
data file contained in it?

> I went ahead and changed the folder back to just degrees 
> before receiving this email.  

OK so just to be clear. Your path to your python file is now

C:\Users\leitm\Desktop\AI\degrees\degrees.py

Is that correct?

And the path to your data is:

C:\Users\leitm\Desktop\AI\degrees\small

Is that correct?

> I will try again tomorrow with the forward slashing to see if that helps at all. 

I've no idea if that will make a difference,
its been a while since I used Python on windows.

> Also, how to do I create a directory for the small folder?

Now you have confused me!
A directory and a folder are the same thing.
You would normally just use your file manager tool
to create a folder. (You can of course use the
command line or even do it from python, but for
this purpose using file manager is simpler)

-- 
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 Jan 27 04:52:09 2021
From: __peter__ at web.de (Peter Otten)
Date: Wed, 27 Jan 2021 10:52:09 +0100
Subject: [Tutor] Python Error Message
In-Reply-To: <rurag0$118$1@ciao.gmane.io>
References: <ruqgnr$veu$1@ciao.gmane.io>
 <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> <rurag0$118$1@ciao.gmane.io>
Message-ID: <2c74c2f9-8cd6-798f-5915-6693823f7c67@web.de>

On 27/01/2021 10:07, Alan Gauld via Tutor wrote:
> On 27/01/2021 03:36, Nirel Leitman via Tutor wrote:
>> Thank you.  And yes, degrees.py is also a folder name along with small.
>
> In that case you are trying to get Python to execute a folder, which
> won't work.

When you invoke the interpreter with a directory

PS C:\Users\Peter> py some_folder

Python will look for a file

some_folder/__main__.py

and fail with an error message similar to the one that the OP got:

C:\Program Files\Python39-32\python.exe: can't find '__main__' module in
'C:\\Users\\Peter\\some_folder'

Nirel, do yourself and us a favor and use the .py suffix for Python
files exclusively. Adding .py to a directory can even confuse the experts.

From __peter__ at web.de  Wed Jan 27 04:52:09 2021
From: __peter__ at web.de (Peter Otten)
Date: Wed, 27 Jan 2021 10:52:09 +0100
Subject: [Tutor] Python Error Message
In-Reply-To: <rurag0$118$1@ciao.gmane.io>
References: <ruqgnr$veu$1@ciao.gmane.io>
 <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> <rurag0$118$1@ciao.gmane.io>
Message-ID: <2c74c2f9-8cd6-798f-5915-6693823f7c67@web.de>

On 27/01/2021 10:07, Alan Gauld via Tutor wrote:
> On 27/01/2021 03:36, Nirel Leitman via Tutor wrote:
>> Thank you.  And yes, degrees.py is also a folder name along with small.
> 
> In that case you are trying to get Python to execute a folder, which
> won't work.

When you invoke the interpreter with a directory

PS C:\Users\Peter> py some_folder

Python will look for a file

some_folder/__main__.py

and fail with an error message similar to the one that the OP got:

C:\Program Files\Python39-32\python.exe: can't find '__main__' module in 
'C:\\Users\\Peter\\some_folder'

Nirel, do yourself and us a favor and use the .py suffix for Python 
files exclusively. Adding .py to a directory can even confuse the experts.


From manpritsinghece at gmail.com  Wed Jan 27 11:21:19 2021
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 27 Jan 2021 21:51:19 +0530
Subject: [Tutor] problem regarding re
Message-ID: <CAO1OCwZfyx+jTbj2YT5k1RtVKfrJiL-mUALK8ieOtgFeRSJv9Q@mail.gmail.com>

Dear Sir ,

Consider a problem given below

re.sub(r'\\', "", 'acd\m')

gives the output = acdm as re.sub will replace the "\" in "acd\m" with "" .

but when i am doing  re.sub(r'\\', "", 'acd\b') why is it not replacing "\"
with "". why i am getting the answer as 'acd\x08' .  How can I get acdb ?
kindly put some light on it.

Thanks
Manprit Singh

From mats at wichmann.us  Wed Jan 27 11:58:08 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Wed, 27 Jan 2021 09:58:08 -0700
Subject: [Tutor] problem regarding re
In-Reply-To: <CAO1OCwZfyx+jTbj2YT5k1RtVKfrJiL-mUALK8ieOtgFeRSJv9Q@mail.gmail.com>
References: <CAO1OCwZfyx+jTbj2YT5k1RtVKfrJiL-mUALK8ieOtgFeRSJv9Q@mail.gmail.com>
Message-ID: <eb4ec298-4f00-aeb5-e54f-63c65c8d0bf8@wichmann.us>

On 1/27/21 9:21 AM, Manprit Singh wrote:
> Dear Sir ,
> 
> Consider a problem given below
> 
> re.sub(r'\\', "", 'acd\m')
> 
> gives the output = acdm as re.sub will replace the "\" in "acd\m" with "" .
> 
> but when i am doing  re.sub(r'\\', "", 'acd\b') why is it not replacing "\"
> with "". why i am getting the answer as 'acd\x08' .  How can I get acdb ?
> kindly put some light on it.

Because the string you are operating on was not entered as a raw string, 
and thus was interpreted by Python. Since \b is a Python-recognized 
escape there's no backslash there when you go to substitute on it.  That 
didn't happen with the first string since \m has no special meaning to 
Python.



From leitman375 at yahoo.com  Wed Jan 27 12:39:09 2021
From: leitman375 at yahoo.com (Nirel Leitman)
Date: Wed, 27 Jan 2021 17:39:09 +0000 (UTC)
Subject: [Tutor] Python Error Message
In-Reply-To: <rurag0$118$1@ciao.gmane.io>
References: <ruqgnr$veu$1@ciao.gmane.io>
 <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> <rurag0$118$1@ciao.gmane.io>
Message-ID: <1579574113.559245.1611769149057@mail.yahoo.com>

 I renamed the folder degrees and inside this folder contains 2 folders: small and large that consist of data.? When I go to properties on the degrees.py it shows this:?C:\Users\leitm\Desktop\AI\degrees?and not?C:\Users\leitm\Desktop\AI\degrees\degrees.py but the path to my data does show:?C:\Users\leitm\Desktop\AI\degrees\small.Are there any further suggestions on how I can make this work?? Thank you again for your time.
And thank you, I didn't know a directory and a folder were the same thing.? Thank you for clearing that for me.
I have also adjusted the degrees.py code as I noticed it was incorrect and not finished.? Here is the updated version:
import?csvimport?sys
from?util?import?Node,?StackFrontier,?QueueFrontier
#?Maps?names?to?a?set?of?corresponding?person_idsnames?=?{}
#?Maps?person_ids?to?a?dictionary?of:?name,?birth,?movies?(a?set?of?movie_ids)people?=?{}
#?Maps?movie_ids?to?a?dictionary?of:?title,?year,?stars?(a?set?of?person_ids)movies?=?{}

def?load_data(directory):????"""????Load?data?from?CSV?files?into?memory.????"""????#?Load?people????with?open(f"{directory}/people.csv",?encoding="utf-8")?as?f:????????reader?=?csv.DictReader(f)????????for?row?in?reader:????????????people[row["id"]]?=?{????????????????"name":?row["name"],????????????????"birth":?row["birth"],????????????????"movies":?set()????????????}????????????if?row["name"].lower()?not?in?names:????????????????names[row["name"].lower()]?=?{row["id"]}????????????else:????????????????names[row["name"].lower()].add(row["id"])
????#?Load?movies????with?open(f"{directory}/movies.csv",?encoding="utf-8")?as?f:????????reader?=?csv.DictReader(f)????????for?row?in?reader:????????????movies[row["id"]]?=?{????????????????"title":?row["title"],????????????????"year":?row["year"],????????????????"stars":?set()????????????}
????#?Load?stars????with?open(f"{directory}/stars.csv",?encoding="utf-8")?as?f:????????reader?=?csv.DictReader(f)????????for?row?in?reader:????????????try:????????????????people[row["person_id"]]["movies"].add(row["movie_id"])????????????????movies[row["movie_id"]]["stars"].add(row["person_id"])????????????except?KeyError:????????????????pass

def?main():????if?len(sys.argv)?>?2:????????sys.exit("Usage:?python?degrees.py?[directory]")????directory?=?sys.argv[1]?if?len(sys.argv)?==?2?else?"large"
????#?Load?data?from?files?into?memory????print("Loading?data...")????load_data(directory)????print("Data?loaded.")
????source?=?person_id_for_name(input("Name:?"))????if?source?is?None:????????sys.exit("Person?not?found.")????target?=?person_id_for_name(input("Name:?"))????if?target?is?None:????????sys.exit("Person?not?found.")
????path?=?shortest_path(source,?target)
????if?path?is?None:????????print("Not?connected.")????else:????????degrees?=?len(path)????????print(f"{degrees}?degrees?of?separation.")????????path?=?[(None,?source)]?+?path????????for?i?in?range(degrees):????????????person1?=?people[path[i][1]]["name"]????????????person2?=?people[path[i?+?1][1]]["name"]????????????movie?=?movies[path[i?+?1][0]]["title"]????????????print(f"{i?+?1}:?{person1}?and?{person2}?starred?in?{movie}")

def?shortest_path(source,?target):????"""????Returns?the?shortest?list?of?(movie_id,?person_id)?pairs????that?connect?the?source?to?the?target.
????If?no?possible?path,?returns?None.????"""
????explored?=?set([])????frontier?=?[source]????parents?=?{}????while?len(frontier)?>?0:????????person?=?frontier.pop(0)????????if?person?==?target:????????????break????????explored.add(person)????????for?(m,?p)?in?neighbors_for_person(person):????????????if?not?p?in?frontier?and?not?p?in?explored:????????????????frontier.append(p)????????????????parents[p]?=?(m,?person)????if?not?target?in?parents:????????return?None????path?=?[]????person?=?target????while?person?!=?source:????????m,?p?=?parents[person]????????path.append((m,?person))????????person?=?p????path?=?path[::-1]????return?path???????????????????????
def?person_id_for_name(name):????"""????Returns?the?IMDB?id?for?a?person's?name,????resolving?ambiguities?as?needed.????"""????person_ids?=?list(names.get(name.lower(),?set()))????if?len(person_ids)?==?0:????????return?None????elif?len(person_ids)?>?1:????????print(f"Which?'{name}'?")????????for?person_id?in?person_ids:????????????person?=?people[person_id]????????????name?=?person["name"]????????????birth?=?person["birth"]????????????print(f"ID:?{person_id},?Name:?{name},?Birth:?{birth}")????????try:????????????person_id?=?input("Intended?Person?ID:?")????????????if?person_id?in?person_ids:????????????????return?person_id????????except?ValueError:????????????pass????????return?None????else:????????return?person_ids[0]

def?neighbors_for_person(person_id):????"""????Returns?(movie_id,?person_id)?pairs?for?people????who?starred?with?a?given?person.????"""????movie_ids?=?people[person_id]["movies"]????neighbors?=?set()????for?movie_id?in?movie_ids:????????for?person_id?in?movies[movie_id]["stars"]:????????????neighbors.add((movie_id,?person_id))????return?neighbors

if?__name__?==?"__main__":????main()

    On Wednesday, January 27, 2021, 02:07:47 AM MST, Alan Gauld via Tutor <tutor at python.org> wrote:  
 
 On 27/01/2021 03:36, Nirel Leitman via Tutor wrote:
> Thank you.? And yes, degrees.py is also a folder name along with small. 

In that case you are trying to get Python to execute a folder, which
won't work.

>? I was told that file names should have .py at the end of it so 
> that Python can recognize it.

Its so that the OS can recognize it as a python file and call
python when you double click on it. Python is happy to execute
the file even without the .py. But it is only files,
not folders, that need the .py extension.

So you need to rename your folder to degrees.
Then inside the degrees folder you need to store your
degrees.py file.
You also need to create another folder inside degrees
called small. I'm not sure what you store in small,
presumably some kind of data file?

Also given your code defaults to large there should
also be a folder called large with another(bigger?)
data file contained in it?

> I went ahead and changed the folder back to just degrees 
> before receiving this email.? 

OK so just to be clear. Your path to your python file is now

C:\Users\leitm\Desktop\AI\degrees\degrees.py

Is that correct?

And the path to your data is:

C:\Users\leitm\Desktop\AI\degrees\small

Is that correct?

> I will try again tomorrow with the forward slashing to see if that helps at all. 

I've no idea if that will make a difference,
its been a while since I used Python on windows.

> Also, how to do I create a directory for the small folder?

Now you have confused me!
A directory and a folder are the same thing.
You would normally just use your file manager tool
to create a folder. (You can of course use the
command line or even do it from python, but for
this purpose using file manager is simpler)

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


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

From alan.gauld at btinternet.com  Wed Jan 27 17:56:19 2021
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 27 Jan 2021 22:56:19 +0000
Subject: [Tutor] Python Error Message
In-Reply-To: <1579574113.559245.1611769149057@mail.yahoo.com>
References: <ruqgnr$veu$1@ciao.gmane.io>
 <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> <rurag0$118$1@ciao.gmane.io>
 <1579574113.559245.1611769149057@mail.yahoo.com>
Message-ID: <a33dc585-b96e-7262-5086-02a2ae96c31d@btinternet.com>


On 27/01/2021 17:39, Nirel Leitman wrote:
> I renamed the folder degrees and inside this folder contains 2
> folders: small and large that consist of data.?

Good so far.

> When I go to properties on the degrees.py it shows
> this:?C:\Users\leitm\Desktop\AI\degrees?and
> not?C:\Users\leitm\Desktop\AI\degrees\degrees.py

How are you going to the properties of degrees.py?

Is it in your IDE/Editor or are you using the OS/File manager?

I think the safest way to make this work is to open your python file in
the editor then choose Save As...? and save it in the degrees folder
as degrees.py.

Then exit the editor completely and try running the newly saved file.


> I have also adjusted the degrees.py code as I noticed it was incorrect
> and not finished.

To be honest not being finished doesn't matter. most professional
programmers
don't even try to create a finished program in one go. They start
with one function and get it working(*). In your case they would probably
just have the load_data function. and a few print statements to prove
it worked. Only after the data is loading properly would you proceed to
build the next function (shortest_path say, or maybe person_id. It doesn't
matter too much which so long as you can think of a way of calling it
with different test conditions(including errors!)) .

That way you always know where the new bugs lie - because you
know the folder code works, so it must be the new stuff! If you try to
write the whole program before testing it you have no idea where
the bugs are hiding.

(*)In fact many modern programmers don;t even wait till they have
written a function to start testing. They will deliberately try to run
unwritten
code to ensure it fails in the way they expect. Then fix the bugs by
writing
the code - often just a few lines at a time. However, that's quite
intensive
and requires a lot of experience of how to test. For now a few print
statements
is probably close enough!

Incidentally, your code just screams out "Use OOP"!" You have at least
two obvious class candidates (Person, Movie) and instantiating objects of
those classes and building collections of them would simplify your top
level code
significantly. However, if you are not yet familiar with classes and
objects don't worry, your approach will still work, it just takes a little
bit more 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


-- 
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 andy-rhodes at lambdastudents.com  Wed Jan 27 19:17:26 2021
From: andy-rhodes at lambdastudents.com (andy-rhodes)
Date: Wed, 27 Jan 2021 18:17:26 -0600
Subject: [Tutor] Trouble Learning Python
Message-ID: <177465a1be4.ef2a00ac647699.1048736627021502944@lambdastudents.com>

I have a couple of questions. I can't get this.



2.3 Add two Boolen variables together to equal 0 and again to equal 1.

Create a variable called?zero?that adds together two boolean values and returns?0. Create another variable called?one?that adds together two other boolean values and returns?1





#?Create?your?variables?here



zero?=?False

one?=?True



my_age?=?35

your_age?=?50





zero?=?my_age?==?your_age



print?(zero)



bill_age?=?65



Msry_age?=?65



one?=?bill_age?==?Msry_age



print?(one)



this is my attempt which gets errors




2.4 Let's create a dictionary!

We'll make a dictionary that contains just a few entries. Remember that a Python dictionary consists of key:value pairs. The keys are like the name of the item and the value tells us something about that item.

Your dictionary will be have three entries (three keys in this case) and a value for each key. We'll choose types of fruit and how many we have of each. A basic dictionary structure with the name?myfruit?was created for you using the { } - fill in the rest!



#?Create?a?dictionary

#?Delete?fruit1,?fruit2,?num1,?num2?and?then

#?uncomment?and?fill?in?with?YOUR?VALUES





?myfruit?=?{'banana':num1,?'kiwi'num2}






Andy?Rhodes

Student

Full-Stack Web Development?|?Lambda School

He/Him


















tel:832-439-0708








mailto:andy-rhodes at lambdastudents.com








https://www.lambdaschool.com/








1913 Pagemill Lane, Conroe, TX 77304














https://www.facebook.com/iovercame/




https://twitter.com/skinnyman180




https://www.linkedin.com/in/arhodes09/




https://www.instagram.com/stdjar42/




















https://www.hubspot.com/email-signature-generator?utm_source=create-signature

From alan.gauld at yahoo.co.uk  Thu Jan 28 04:25:05 2021
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 28 Jan 2021 09:25:05 +0000
Subject: [Tutor] Trouble Learning Python
In-Reply-To: <177465a1be4.ef2a00ac647699.1048736627021502944@lambdastudents.com>
References: <177465a1be4.ef2a00ac647699.1048736627021502944@lambdastudents.com>
Message-ID: <rutvti$135$1@ciao.gmane.io>

On 28/01/2021 00:17, andy-rhodes wrote:

> 2.3 Add two Boolen variables together to equal 0 and again to equal 1.

First off I've got to say that this is a terrible question. It's
asking you to do something you should never do in practice.
Addition is not a boolean operation. It only works because internally
python implements boolean values as integers! That's a fact
you should just ignore and only use boolean operators on
boolean values, it will help keep you sane!

> Create a variable called?zero?that adds together two boolean values and returns?0. 

Remember that boolean vales should only be True or False.

So you need to add:
- True to True,
- True to False or
- False to False.

Those are the only valid additions you can perform.

> #?Create?your?variables?here
> 
> zero?=?False
> one?=?True
> 
> my_age?=?35
> your_age?=?50

The above both need to be True or False. Nothing else
is a boolean value.

> zero?=?my_age?==?your_age

But that's not addition.
It's a comparison which is a valid boolean expression.

"Sensible" additions would be:

zero = False + False
one = True + False

> bill_age?=?65
> Msry_age?=?65

Again boolean variables should only be True or false
So age would not be boolean.

> one?=?bill_age?==?Msry_age
> print?(one)

Again this is not addition but comparison.
If this is part of the question then it really is a terrible question.
In fact it looks like it comes from the very distant past when Python
didn't have true boolean types.

> this is my attempt which gets errors

Umm, where?

> 2.4 Let's create a dictionary!
> 
> We'll make a dictionary that contains just a few entries. 
> Remember that a Python dictionary consists of key:value pairs. 
> The keys are like the name of the item and the value tells us 
> something about that item.

> Your dictionary will be have three entries (three keys in this case) 
> and a value for each key. We'll choose types of fruit and how many 
> we have of each. A basic dictionary structure with the name?myfruit 
> was created for you using the { } - fill in the rest!

This is more promising.

> #?Create?a?dictionary
> #?Delete?fruit1,?fruit2,?num1,?num2?and?then
> #?uncomment?and?fill?in?with?YOUR?VALUES

> ?myfruit?=?{'banana':num1,?'kiwi'num2}
This kind of falls apart though. It's not clear exactly what
you need to do and the single line of code doesn't match
the commentary.

I think they are asking you to assign numeric values to
num1,num2 (and presumably num3 since it says 3 entries,
although it only provides 2!)) Or maybe it started as

myfruit = {fruit1:num1, fruit2:num2, fruit3:num3}

And you need to replace the fruit and number names with
literal values? In which case remember that the key
and value are separated by a colon(:) and the pairs
are separated by commas.


-- 
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  Thu Jan 28 13:34:19 2021
From: jf_byrnes at comcast.net (Jim Byrnes)
Date: Thu, 28 Jan 2021 12:34:19 -0600
Subject: [Tutor] Fwd: Re: Rerouting a traceback
In-Reply-To: <fccb224a-19dc-0756-6b3c-d17609c3b381@comcast.net>
References: <fccb224a-19dc-0756-6b3c-d17609c3b381@comcast.net>
Message-ID: <0cb8eaac-2a70-1666-e5c1-b1909b5d1e45@comcast.net>



I goofed, I sent this reply straight to Mats not to the list.

-------- Forwarded Message --------
Subject: Re: Rerouting a traceback
Date: Tue, 26 Jan 2021 15:02:16 -0600
From: Jim Byrnes <jf_byrnes at comcast.net>
To: Mats Wichmann <mats at wichmann.us>

On 1/25/21 9:15 PM, Mats Wichmann wrote:
> 
> On 1/25/21 7:21 PM, Jim Byrnes wrote:
>> Linux Mint 20 - Python 3.8
>>
>> Is it possible to reroute a traceback to a GUI wintow?
> 
> It's software, so it's possible...

snip>

> If the script you launch is your own - that is, if you feel like 
> modifying it - it can just pop up a simple message box. This might end 
> up being sufficient:

I wrote the scripts.

> from tkinter import messagebox
> 
> messagebox.showerror("FAILED", "error message from the failure")
> 

The scripts are not really gui's. I just use pyautogui to provide a 
convenient way to enter a date. I mentioned pysimplegui (a wrapper 
around tkinter) because I might be able to use it's debug window to 
print the traceback, so far I haven't been able to figure it out.

> but you'll need to ampliy what you need and who controls what in this 
> scenario, it might be more complicated.

The code below is the heart of a lengthy function. Before the loop I 
gather the info it needs to process.


     # Get historical stock prices from yahoo using yfinance
     for stock in stocks:
         while True:
             try:
                 ticker = yf.Ticker(stock)
                 hist = ticker.history(start=day)
                 close_price = hist.loc[day]['Close']
                 closing_prices.append(close_price)
             except:
                 print ('yfinance JSONDecodeError DAILY, retyring')
                 continue
             break

After the loop I process the info in the spreadsheet.

Sometimes it takes a little while for the loop to complete. Mean while I 
watch the spreadsheet waiting for it to up date. After a while I decide 
something went wrong and then rerun the script from the terminal to see 
the trackback.

What I want to do is see the traceback when the problem occurs instead 
of waiting and then rerunning the script in the terminal. The errors are 
not with the scripts code. I may have entered a date when the markets 
were closed or yahoo just timed out. The traceback lets me figure that out.

Thanks,  Jim

From david at graniteweb.com  Sat Jan 30 16:58:02 2021
From: david at graniteweb.com (David Rock)
Date: Sat, 30 Jan 2021 15:58:02 -0600
Subject: [Tutor] Trouble Learning Python
In-Reply-To: <rutvti$135$1@ciao.gmane.io>
References: <177465a1be4.ef2a00ac647699.1048736627021502944@lambdastudents.com>
 <rutvti$135$1@ciao.gmane.io>
Message-ID: <20210130215802.GK13183@apple.graniteweb.com>

* Alan Gauld via Tutor <tutor at python.org> [2021-01-28 09:25]:
> On 28/01/2021 00:17, andy-rhodes wrote:
> 
> > 2.3 Add two Boolen variables together to equal 0 and again to equal 1.
> 
> First off I've got to say that this is a terrible question. It's
> asking you to do something you should never do in practice.
> Addition is not a boolean operation. It only works because internally
> python implements boolean values as integers! That's a fact
> you should just ignore and only use boolean operators on
> boolean values, it will help keep you sane!

These appear to be questions from some kind of coursework.  Is it available
online and do you have a link you can share with us so we can read it
ourselves?  There may be some transcription challenges happening that we may be
able to clear up if we can see it.

-- 
David Rock
david at graniteweb.com

From mhysnm1964 at gmail.com  Sun Jan 31 01:16:29 2021
From: mhysnm1964 at gmail.com (mhysnm1964 at gmail.com)
Date: Sun, 31 Jan 2021 17:16:29 +1100
Subject: [Tutor] extracting information from a complex dict.
Message-ID: <01d701d6f798$9f32e210$dd98a630$@gmail.com>

All,

 

Using windows and python 3.8.

 

I need to convert a complex dict into a list. Then I am saving the list as a
CSV. I know there is more than likely a library which can convert the tree
(dict) into a CSV file. But I want to learn recursive functions. I have
learnt the basics when using maths functions. Thus I understand the basic
logic of recursive functions. Now I am trying to do something more
difficult. 

 

The basic dict structure is:

 

{

    "A": {

        "A A Attanasio": {

            "A A Attanasio": [

                "Wyvern plot.txt",

                "Wyvern.mp3"

            ]

        }

    }

}

 

I extracted the above from a JSON file which the Dict is based upon. Basic
structure:

*	The first dict has a maximum of 26 entereies. A to z. Calling this
level 1.
*	The first child can have an unknown number of dict's. Only dicts
exist at this level. For ease of reading I will call this level 2 dict.

*	Level 2 dicts can have a value of None. Easily tested for.

*	The child of level 2 dict, ease of reading level 3 dict:

*	Level 3 dict's contains a list or
*	Another dict containing another level 3 dict structure using my
convention is Level 4 dict. Nothing is deeper than this.

 

Outcome: I want to build a list that contains the following list structure:

[

              ['a', 'author name', author name', bookt title],

              ['a', 'author name', author name', bookt title]

]

 

This might be easier if there was a parent key / value. But there is not.
The file is to large to manually change this. I would have to write some
code to insert the parent key. I am hoping there is a way not to do that.

 

My logic (thinking) is (starting from the top of the tree and working your
way down):

1.	The following variables need to be passed into the function (I
think):

a.	List containing the above structure that I want.
b.	A list of all the keys used to get to the value which contains the
list.
c.	The current key which either contains another dict or the list.
d.	The First call is the full dict and each call after this point is
the dict for the next level down. Basically popping the dict.

2.	Test the dict value to see if it contains a None. If does, then only
store the first three elements of the array as there is no books titles.
3.	Test the dict value to see if it contains a list. If so, then append
to the above list structure with all values.
4.	If a dict, then add to the key list and only return the dict
contained in the value. 

 

What I am not sure if the above logic will work or if I should be using a
loops within the recursive function. I don't have any code to show as I am
not sure how to start. Done searching and seen examples. Still confused.

 

Hope someone can give me some pointers.

 

Sean 


From cs at cskk.id.au  Sun Jan 31 01:54:15 2021
From: cs at cskk.id.au (Cameron Simpson)
Date: Sun, 31 Jan 2021 17:54:15 +1100
Subject: [Tutor] extracting information from a complex dict.
In-Reply-To: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
References: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
Message-ID: <YBZUF4vpxUB7ufhV@cskk.homeip.net>

On 31Jan2021 17:16, Sean Murphy <mhysnm1964 at gmail.com> wrote:
>Using windows and python 3.8.

Thanks for this context.

>I need to convert a complex dict into a list. Then I am saving the list 
>as a CSV.

That part is easy. Prepare the list first. Then later see the builtin 
'csv" module.

>I know there is more than likely a library which can convert the tree
>(dict) into a CSV file.

Less likely - your nested dict structure seems quite special purpose.

>But I want to learn recursive functions. I have
>learnt the basics when using maths functions. Thus I understand the basic
>logic of recursive functions. Now I am trying to do something more
>difficult.
>
>The basic dict structure is:
>
>{
>    "A": {
>        "A A Attanasio": {
>            "A A Attanasio": [
>                "Wyvern plot.txt",
>                "Wyvern.mp3"
>            ]
>        }
>    }
>}
>
>I extracted the above from a JSON file which the Dict is based upon. 

Good. This means it will only contain dicts and lists (and strings and 
numbers and None). No funny classes, just the basics.

>Basic
>structure:
>
>*	The first dict has a maximum of 26 entereies. A to z. Calling this
>level 1.

Ok, a mapping of starting letter to dicts mapping author names to 
something.

>*	The first child can have an unknown number of dict's. Only dicts
>exist at this level. For ease of reading I will call this level 2 dict.

A mapping of author names to something.

>*	Level 2 dicts can have a value of None. Easily tested for.

Yes.

>*	The child of level 2 dict, ease of reading level 3 dict:
>
>*	Level 3 dict's contains a list or
>*	Another dict containing another level 3 dict structure using my
>convention is Level 4 dict. Nothing is deeper than this.

So a list of book titles (filenames?), or possibly another nested 
author->list mapping? Do you know why the extra depth?

>Outcome: I want to build a list that contains the following list 
>structure:
>
>[
>              ['a', 'author name', author name', bookt title],
>              ['a', 'author name', author name', bookt title]
>]

I'm going to assume you mistyped something there. Do you mean:

    ['a', 'author name', 'book title']

such as:

    ['A', 'A A Attanasio', 'Wyvern plot.txt']

?

>This might be easier if there was a parent key / value. But there is 
>not.
>The file is to large to manually change this. I would have to write some
>code to insert the parent key. I am hoping there is a way not to do that.
>
>
>My logic (thinking) is (starting from the top of the tree and working your
>way down):
>
>1.	The following variables need to be passed into the function (I
>think):
>
>a.	List containing the above structure that I want.

Right. Pass this same list to every recursive call, that way your 
function can add rows to the list as they are found.

>b.	A list of all the keys used to get to the value which contains the
>list.

Ah, so it might be:

    ['A', 'A A Attanasio', 'A A Attanasio', 'Wyvern plot.txt', 'Wyvern.mp3']

for the Wyvern stuff 3 levels deep? Or even:

    ['A', 'A A Attanasio', 'A A Attanasio', 'Wyvern plot.txt']
    ['A', 'A A Attanasio', 'A A Attanasio', 'Wyvern.mp3']

>c.	The current key which either contains another dict or the list.

Sounds good.

>d.	The First call is the full dict and each call after this point is
>the dict for the next level down. Basically popping the dict.
>
>2.	Test the dict value to see if it contains a None. If does, then only
>store the first three elements of the array as there is no books titles.
>3.	Test the dict value to see if it contains a list. If so, then append
>to the above list structure with all values.
>4.	If a dict, then add to the key list and only return the dict
>contained in the value.
>
>What I am not sure if the above logic will work or if I should be using a
>loops within the recursive function.

If your structure was fixed depth (eg 'A' => 'Author Name' => 
list-of-filenames) a couple of nested loops would be easier. However, it 
varies. Even though only slightly, you're still well off with a 
recursive function.

>I don't have any code to show as I am
>not sure how to start. Done searching and seen examples. Still confused.

Fortunately, you have pretty much written out all the logic correctly 
above.

Your plan is to call your function whenever you have a dict, but 
otherwise stop there and add to your list if it isn't None.

Your plan to collect the keys is also good.

Start by writing the function itself _first_, handing it the state 
you've identified as required at any given point:

    def gather_titles(big_list, previous_keys, subitem):

i.e. the list you're adding things to, the ancestral keys, and the item 
you're examining at this point in the tree of dicts: it might be a 
deeper dict, or a list or None per your description above.

When you start, the parameters have obvious values:


    author_list = []
    gather_titles(author_list, [], the_dict_from_the_json)

i.e. your intially empty list, no previous keys, the top level dict.

So what do you do inside the function? You wrote it out above:

- if subitem is None, do nothing
- if subitem is a list, add it along with the ancestral keys to big_list
- if subitem is a dict, recurse for each element in the dict
- otherwise something unexpected! raise an exception!

That's an if-statement:

    if subitem is None:
        pass
    elif isinstance(subitem, list):
        add to big_list here
    elif isinstance(subitem, dict):
        recurse for each item in the dict
    else:
        raise RuntimeError(
            "at keys %r got an unexpected type %s:%r"
            % (previous_keys, type(subitem), subitem))

Plenty of people wouldn't bother with the exception, but it is good 
defensive programming: handle the known cases, then explode with a 
informative exception if something is somehow unhandled. Much better 
than having the unhandled type silently ignored.

The if-statement is the entire body of your function.

Now fill in the bodies of the second and third if-statement choices. If 
you get stuck, put in print statements to see what values you're working 
against.

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

From __peter__ at web.de  Sun Jan 31 06:23:43 2021
From: __peter__ at web.de (Peter Otten)
Date: Sun, 31 Jan 2021 12:23:43 +0100
Subject: [Tutor] extracting information from a complex dict.
In-Reply-To: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
References: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
Message-ID: <a84818b7-5173-3b76-36ae-c51f7083a5a3@web.de>

On 31/01/2021 07:16, mhysnm1964 at gmail.com wrote:

> I need to convert a complex dict into a list. Then I am saving the list as a
> CSV. I know there is more than likely a library which can convert the tree
> (dict) into a CSV file. But I want to learn recursive functions. I have
> learnt the basics when using maths functions. Thus I understand the basic
> logic of recursive functions. Now I am trying to do something more
> difficult.
>
>
>
> The basic dict structure is:

I'd like to suggest an approach where the dict structure doesn't matter
much. It's sufficient that you may have arbitrarily nested dicts and
lists, and scalar values.

When you encounter a list you want

[first-item]
[second-item]
[third-item]
...

and for a dict you want

[first-key, first-value]
[second-key, second-value]
...

For any other value you want just that

[value]

Now, how to combine these parts in such a way that e. g.

tree = {1: [2, 3, 4]}

gives

[1, 2]
[1, 3]
[1, 4]

? If the structure were fixed you'd use

for key, value in tree.items():
     for item in value:
         print([key, item])

but since you don't know the actual nesting you need to check

if isinstance(tree, dict):
     for key, value in tree.items():
         print([key, value])
elif isinstance(tree, list):
     for value in tree:
         print([value])
else:
     print([tree])

That works not just for a dict but for an arbitrary node in our tree --
let's turn it into a function

def process(tree, path=()):

(As we need a way to remember the upwards part of the tree we provide
the path argument. I used a tuple to appease the linters, but a list
would work here, too, as long as you do not actually mutate the path
variable.)

     if isinstance(tree, dict):
         for key, value in tree.items():
             process(value, path + (key,))
     elif isinstance(tree, list):
         for value in tree:
             process(value, path)
             # the above line flattens nested lists
             # you might instead want
     else:
         print(path + (tree,))


This is classical recursion, and as written it's not very flexible. If
you want to filter out None values and dump to CSV instead of printing
the tuples you need to rewrite the process() function.
One way to make the function more flexible is to have it accept a
callback function:

def process_cb(tree, path=(), process_leaf=print):
     if isinstance(tree, dict):
         for key, value in tree.items():
             process_cb(value, path + (key,), process_leaf)
     elif isinstance(tree, list):
         for value in tree:
             process_cb(value, path, process_leaf)
     else:
         process_leaf(path + (tree,))


# example usage
writer = csv.writer(sys.stdout)
def dump(path):
     if path[-1] is None:
         print("suppressed", path, file=sys.stderr)
     else:
         writer.writerow(path)

process_cb(sample, process_leaf=dump)

The cleaner option is to return the tuples upwards. You may try your
hands at rewriting process() in such a way. However, the disadvantage is
that you build the complete list before you start printing anything.

A structurally identical but more elegant solution is to use a generator
instead of a regular function:

def process_gen(tree):
     if isinstance(tree, dict):
         for key, value in tree.items():
             for rest in process_gen(value):
                 yield (key,) + rest
     elif isinstance(tree, list):
         for value in tree:
             yield from  process_gen(value)
     else:
         yield((tree,))

writer = csv.writer(sys.stdout)
writer.writerows(
     path for path in process_gen(sample) if path[-1] is not None
)

This "returns" a row as it is seen so that i can be processed
immediately on the top level of the script. As the call stack is
preserved execution of the generator code can then continue where it paused.

This is the technique that you have already seen in os.walk().

From __peter__ at web.de  Sun Jan 31 06:23:43 2021
From: __peter__ at web.de (Peter Otten)
Date: Sun, 31 Jan 2021 12:23:43 +0100
Subject: [Tutor] extracting information from a complex dict.
In-Reply-To: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
References: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
Message-ID: <a84818b7-5173-3b76-36ae-c51f7083a5a3@web.de>

On 31/01/2021 07:16, mhysnm1964 at gmail.com wrote:

> I need to convert a complex dict into a list. Then I am saving the list as a
> CSV. I know there is more than likely a library which can convert the tree
> (dict) into a CSV file. But I want to learn recursive functions. I have
> learnt the basics when using maths functions. Thus I understand the basic
> logic of recursive functions. Now I am trying to do something more
> difficult.
> 
>   
> 
> The basic dict structure is:

I'd like to suggest an approach where the dict structure doesn't matter 
much. It's sufficient that you may have arbitrarily nested dicts and 
lists, and scalar values.

When you encounter a list you want

[first-item]
[second-item]
[third-item]
...

and for a dict you want

[first-key, first-value]
[second-key, second-value]
...

For any other value you want just that

[value]

Now, how to combine these parts in such a way that e. g.

tree = {1: [2, 3, 4]}

gives

[1, 2]
[1, 3]
[1, 4]

? If the structure were fixed you'd use

for key, value in tree.items():
     for item in value:
         print([key, item])

but since you don't know the actual nesting you need to check

if isinstance(tree, dict):
     for key, value in tree.items():
         print([key, value])
elif isinstance(tree, list):
     for value in tree:
         print([value])
else:
     print([tree])

That works not just for a dict but for an arbitrary node in our tree -- 
let's turn it into a function

def process(tree, path=()):

(As we need a way to remember the upwards part of the tree we provide 
the path argument. I used a tuple to appease the linters, but a list 
would work here, too, as long as you do not actually mutate the path 
variable.)

     if isinstance(tree, dict):
         for key, value in tree.items():
             process(value, path + (key,))
     elif isinstance(tree, list):
         for value in tree:
             process(value, path)
             # the above line flattens nested lists
             # you might instead want
     else:
         print(path + (tree,))


This is classical recursion, and as written it's not very flexible. If 
you want to filter out None values and dump to CSV instead of printing 
the tuples you need to rewrite the process() function.
One way to make the function more flexible is to have it accept a 
callback function:

def process_cb(tree, path=(), process_leaf=print):
     if isinstance(tree, dict):
         for key, value in tree.items():
             process_cb(value, path + (key,), process_leaf)
     elif isinstance(tree, list):
         for value in tree:
             process_cb(value, path, process_leaf)
     else:
         process_leaf(path + (tree,))


# example usage
writer = csv.writer(sys.stdout)
def dump(path):
     if path[-1] is None:
         print("suppressed", path, file=sys.stderr)
     else:
         writer.writerow(path)

process_cb(sample, process_leaf=dump)

The cleaner option is to return the tuples upwards. You may try your 
hands at rewriting process() in such a way. However, the disadvantage is 
that you build the complete list before you start printing anything.

A structurally identical but more elegant solution is to use a generator 
instead of a regular function:

def process_gen(tree):
     if isinstance(tree, dict):
         for key, value in tree.items():
             for rest in process_gen(value):
                 yield (key,) + rest
     elif isinstance(tree, list):
         for value in tree:
             yield from  process_gen(value)
     else:
         yield((tree,))

writer = csv.writer(sys.stdout)
writer.writerows(
     path for path in process_gen(sample) if path[-1] is not None
)

This "returns" a row as it is seen so that i can be processed 
immediately on the top level of the script. As the call stack is 
preserved execution of the generator code can then continue where it paused.

This is the technique that you have already seen in os.walk().


From david at graniteweb.com  Sun Jan 31 12:38:12 2021
From: david at graniteweb.com (David Rock)
Date: Sun, 31 Jan 2021 11:38:12 -0600
Subject: [Tutor] extracting information from a complex dict.
In-Reply-To: <YBZUF4vpxUB7ufhV@cskk.homeip.net>
References: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
 <YBZUF4vpxUB7ufhV@cskk.homeip.net>
Message-ID: <20210131173812.GM13183@apple.graniteweb.com>

* Cameron Simpson <cs at cskk.id.au> [2021-01-31 17:54]:
> 
> - otherwise something unexpected! raise an exception!
> 
>     else:
>         raise RuntimeError(
>             "at keys %r got an unexpected type %s:%r"
>             % (previous_keys, type(subitem), subitem))
> 
> Plenty of people wouldn't bother with the exception, but it is good 
> defensive programming: handle the known cases, then explode with a 
> informative exception if something is somehow unhandled. Much better 
> than having the unhandled type silently ignored.

I can't agree with this more.  Just this week I inherited some code at work
where absolutely no regard for handling exceptions was done, and they all
silently get ignored, causing all kinds of unseen issues.  Using an if
statement without planning for the else condition leaves no protection for new
data added later that does not conform to the original logic.  You will never
know something is wrong unless it actually breaks something later.  Things that
"work incorrectly" are insidious because they hide in plain sight.

-- 
David Rock
david at graniteweb.com

From mats at wichmann.us  Sun Jan 31 12:42:00 2021
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 31 Jan 2021 10:42:00 -0700
Subject: [Tutor] extracting information from a complex dict.
In-Reply-To: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
References: <01d701d6f798$9f32e210$dd98a630$@gmail.com>
Message-ID: <49f7b0f3-a7bd-6822-18ae-5620bb4d191c@wichmann.us>

On 1/30/21 11:16 PM, mhysnm1964 at gmail.com wrote:
> All,
> 
>   
> 
> Using windows and python 3.8.
> 
>   
> 
> I need to convert a complex dict into a list. Then I am saving the list as a
> CSV. I know there is more than likely a library which can convert the tree
> (dict) into a CSV file. But I want to learn recursive functions. I have
> learnt the basics when using maths functions. Thus I understand the basic
> logic of recursive functions. Now I am trying to do something more
> difficult.

> Hope someone can give me some pointers.

On a different tack than the useful advice otherwise posted here, the 
pandas library has considerable support for going from JSON formats to 
other formats such as csv, you might want to take a look and see if 
someone has done the hard work for you already (yes it's quite possible 
that the particular format described here will defeat you, but then 
again maybe not).