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: 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: References: Message-ID: 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 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 , passwd=data.ftp_passwd) except ftplib.all_errors as err: # Log the error logging.error(err) else: ftp.cwd(data.ftp_dir) files = 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: 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: References: Message-ID: 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: References: Message-ID: 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 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: References: Message-ID: 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: 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: References: Message-ID: 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: References: 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: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk> Message-ID: 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: References: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk> Message-ID: 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: References: Message-ID: <20210108155619.GF25370@apple.graniteweb.com> * Umar Draz [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: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk> Message-ID: 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 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: References: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk> Message-ID: 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 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: References: <6ee13928-980c-db75-3505-5147839207c8@yahoo.co.uk> Message-ID: 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 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 > 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: 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: References: 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: On 12Jan2021 14:32, 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') 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 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: 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: References: 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: References: <5FFDF954.2080904@sbcglobal.net> Message-ID: <5FFEF81A.2030006@sbcglobal.net> On 01/12/2021 04:44 PM, Cameron Simpson wrote: > On 12Jan2021 14:32, 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') > 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 > 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 "", line 1 for ligand in df: ^ SyntaxError: unexpected EOF while parsing for i in num: File "", line 1 for i in num: ^ SyntaxError: unexpected EOF while parsing name_in = "{}.{}.log".format(ligand, i) Traceback (most recent call last): File "", line 1, in 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 "", line 1, in 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 "", line 1, in name_s = ligand+'-BE' NameError: name 'ligand' is not defined f = open(name_s, 'a') Traceback (most recent call last): File "", line 1, in 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 "", line 1, in 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 "", line 1, in 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> <5FFEF81A.2030006@sbcglobal.net> Message-ID: 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 "", 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 "", 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 "", line 1, in > 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: References: Message-ID: 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: References: <5FFDF954.2080904@sbcglobal.net> <5FFEF81A.2030006@sbcglobal.net> 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 "", 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 "", 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 "", line 1, in >> 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: References: <5FFDF954.2080904@sbcglobal.net> <5FFEF81A.2030006@sbcglobal.net> <5FFF1F9E.5010806@sbcglobal.net> 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" > declaimed the following: > > > > 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> <5FFEF81A.2030006@sbcglobal.net> <5FFF1F9E.5010806@sbcglobal.net> <5FFF5F5C.9000901@sbcglobal.net> Message-ID: 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: References: <5FFDF954.2080904@sbcglobal.net> <5FFEF81A.2030006@sbcglobal.net> <5FFF1F9E.5010806@sbcglobal.net> <5FFF5F5C.9000901@sbcglobal.net> 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: References: <5FFDF954.2080904@sbcglobal.net> <5FFEF81A.2030006@sbcglobal.net> <5FFF1F9E.5010806@sbcglobal.net> <5FFF5F5C.9000901@sbcglobal.net> <600028DC.4070809@sbcglobal.net> 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" > 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> <5FFEF81A.2030006@sbcglobal.net> <5FFF1F9E.5010806@sbcglobal.net> <5FFF5F5C.9000901@sbcglobal.net> <600028DC.4070809@sbcglobal.net> <6000AA7C.3030902@sbcglobal.net> Message-ID: 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: On 14Jan2021 15:33, Stephen P. Molnar 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 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: References: <6000AA7C.3030902@sbcglobal.net> Message-ID: <60019777.7080002@sbcglobal.net> On 01/14/2021 04:30 PM, Cameron Simpson wrote: > On 14Jan2021 15:33, Stephen P. Molnar 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 > _______________________________________________ > 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> <60019777.7080002@sbcglobal.net> Message-ID: 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: References: <6000AA7C.3030902@sbcglobal.net> <60019777.7080002@sbcglobal.net> 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: 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: References: Message-ID: 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: 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> <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: 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: 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: 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 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: References: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@protonmail.com> Message-ID: 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: References: <7u25jSbDvC8rtyPE3ASREHlt4ECI8F0H3l3eY407YY2b43zQRed1U6JnDCmMzwNJnO9f-kxNsqdfpEseDDw0uq9S0gDSEeOjiew4FhfDROw=@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: References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com> 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 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 "", line 1, in ? ? 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> <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com> Message-ID: 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: 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: 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: On 25Jan2021 20:20, Sean Murphy 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 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: 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: References: 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: References: <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com> 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 Sent: Tuesday, 26 January 2021 12:46 PM To: mhysnm1964 at gmail.com Cc: 'Alan Gauld' ; tutor at python.org Subject: Re: [Tutor] storing and saving file tree structure On 25Jan2021 20:20, Sean Murphy 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 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: References: <002c01d6f21c$82ed3c80$88c7b580$@gmail.com> <000e01d6f2fb$5bfd0530$13f70f90$@gmail.com> 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 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: 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: 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: 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: References: Message-ID: 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: References: Message-ID: 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> <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 > 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 > 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> <1521051109.210743.1611681481476@mail.yahoo.com> <2e52cc1e-0670-99fa-a18f-5b2a87b906b0@btinternet.com> Message-ID: 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 >> 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 >> 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: References: 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 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 >>> 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 >>> 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: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> Message-ID: 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: References: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> 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: References: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> 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: 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: References: Message-ID: 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: References: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> 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 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: <3040A42A-ADC6-4491-B5B1-4B67E2027AB7@yahoo.com> <1579574113.559245.1611769149057@mail.yahoo.com> Message-ID: 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: 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: References: 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 To: Mats Wichmann 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: References: <177465a1be4.ef2a00ac647699.1048736627021502944@lambdastudents.com> Message-ID: <20210130215802.GK13183@apple.graniteweb.com> * Alan Gauld via Tutor [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: On 31Jan2021 17:16, Sean Murphy 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 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: 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: 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: References: <01d701d6f798$9f32e210$dd98a630$@gmail.com> Message-ID: <20210131173812.GM13183@apple.graniteweb.com> * Cameron Simpson [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).