From d_wobmann at hotmail.com Tue Jun 2 14:38:36 2020 From: d_wobmann at hotmail.com (Daniel Wobmann) Date: Tue, 2 Jun 2020 18:38:36 +0000 Subject: [Tutor] Python Networkx with file in gexf format Message-ID: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com> Hello everybody, I'm doing a continuing education, with Python being a relatively large part of it. With my basic knowledge I have practically no chance - especially for the project work, which we have to deliver on June 20, 2020. We are not allowed to use Gephi. Everything must be analyzed and derived in Python. So I am dependent on help and thank you for every support, no matter how small. I have a dataset in gexf format about the nodes "students" (student-ID) and "teachers" (teacher-ID), where each node belongs to a school class and has a corresponding gender; for teachers no gender is given. There are 10 school classes, e.g. 1A, 2B, etc. The edges connect the pupil-ID by means of "Origin" and "Destination". The edges are all of the type "Undirected" and weight "1". The "duration" is the duration of all interactions between the nodes (origin and destination); "count" is the number of times the origin and destination have joined together to form an interaction. I have attached the dataset to you. If someone can help me with this, I would send him/her the dataset by mail. And of course I would pay something for the work. So far I have managed to get the system to tell me how many nodes and edges there are and what the average degree per node is. That was it. Now I wish to read out various information from this dataset with Python and the package networkx - and above all to display it graphically. This causes me many difficulties, because in python I want to work with the nodes / edges in the gexf document; but also with the values per item - for example with the value of an ID of a student or with a class name. For this I want to use "networkx". And these are my questions: 1. how can I find out from which data type a feature is? How can I convert the datatype of a feature for example from String to Int (preprocessing engineering)? 2. how can I calculate the number of edges per node (1 origin and how many targets?)? I think this is called "degree", I have seen. What does this code look like? So I want to know how many connections (edges) the node 1551 has to other nodes, for example how many connections the student 1551 has to other students to other students (and teachers). How can I list them per node? What does the code for this look like? For example, how can I calculate the sum of "counts" or "duration" per student ID? How can I use the result of the number of nodes per Student ID to divide them, for example to calculate the average duration? 4. develop and display the graph for the whole dataset What does the code for this look like? 5. how can I display graphs, i.e. connections and nodes of a single school class (clusters?), single nodes (students) of the same class, etc. with different colors? What does the code for this look like? 6. subgraphs: Are they parts of a whole graph, as I understood it, or? How can I display them for example for between two, three classes, ten students per class, for students and teachers together, etc.? Or for example for the connections within a class? What does the code for this look like? 7. are subgraphs also called "subgroups" and "clusters"? What does the code for this look like so that I can graphically represent such properties? What do I concentrate on in the dataset? For example items? values? 8 How can I determine whether or which student is an "influencer" in the class and which student is not an influencer at all? And which pupil is the "influencer" between school classes? Which are the "inluencers" between school classes? What does the code for this look like? 9. how can I remove items. For example, because they represent an outlier? Or simply remove all those items whose "count" is below 10, for example? What does the code for this look like? 10. weight: I have read a lot about it, but I have not been able to figure out what it is and what purpose it serves. What does this tell me? What can I do with it? How can I change this weight? Why is the weight adjusted in different ways, i.e. for certain connections the weight is often set to 2, for others to 3, etc. And above all: Why should I change a weight, i.e. what could be the intention? What would this mean for "my" dataset? Between all origins and destinations, in our case there is weight 1. Why should I change it? Why should it make sense to change weights? In which case would I do this and why? What is the code for changing the weight? 11. How to calculate the following? For example, is this calculated per student or even per cluster (e.g. school class)? Or for which properties is this calculated? - Degree Centrality - Betweenness-Zentralit?t) - Closeness Central Office - Prestige Indegree - Ego Network 12. Link Predictions? I heard that there are ways to use different models (or algorithms?) to predict what other possible connections between nodes or the students (in our case) might look like. For example Jaccard, Common Neighbours, Preferential Attachment, Resource Allocation, etc. What does the code for these look like? I am looking forward to your feedback. Thank you very much and best regards Daniel Wobmann From dvsree123 at gmail.com Tue Jun 2 07:10:56 2020 From: dvsree123 at gmail.com (Divya) Date: Tue, 2 Jun 2020 16:40:56 +0530 Subject: [Tutor] Practice websites Message-ID: Please suggest me some websites where I can practice the very basics like functions, expressions etc.. From alan.gauld at yahoo.co.uk Tue Jun 2 19:00:05 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 3 Jun 2020 00:00:05 +0100 Subject: [Tutor] Practice websites In-Reply-To: References: Message-ID: On 02/06/2020 12:10, Divya wrote: > Please suggest me some websites where I can practice the very basics like > functions, expressions etc.. I'm not sure what you are looking for. There are a couple of web sites with virtual Python interpreters where you can type basic Python code and it will execute it for you. If that's what you want here is one I found. I don't use this service so can't say how good it is but it seems to handle print("hello") ok...! https://repl.it/languages/Python3 But most folks find it easier to download Python to their PC (Or tablet) and use it offline. Especially if you want to process local data or manipulate you machine in some way. If on the other hand you are looking for tutorial information there is a whole page for beginners (one each both non-programmers and existing programmers in other languages). (Or you can try mine - see the link in my .sig Finally, if you want projects or exercises there are some sites that do that too - I think coursera has some. And the Python Challenge website is an interesting way to learn new tricks with Python. I hope that helps, if not you need to be a bit more specific about what you are after. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Tue Jun 2 19:12:04 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 2 Jun 2020 18:12:04 -0500 Subject: [Tutor] Named tuple special methods and attributes start with an underscore? Message-ID: <20200602231204.GF23247@Dream-Machine1> I was reading an article on the collections library (https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html). In it it had the following note: "In Python, methods with leading underscores are usually considered ?private.? Additional methods provided by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are public." This greatly surprised me. So I went to the Python docs (https://docs.python.org/3/library/collections.html#collections.namedtuple) and found: "In addition to the methods inherited from tuples, named tuples support three additional methods and two attributes. To prevent conflicts with field names, the method and attribute names start with an underscore." Huh?!? The mentioned 5 items are: _make, _asdict, _replace, _fields and _field_defaults. Of the items "_replace" is the most surprising as that is already used by Python in other contexts such as str.replace(). These items don't look to be likely field names to be used by anyone. Any illumination for this design decision? To my (perhaps naive) eyes this strikes me as extraordinarily inconsistent Python syntax. -- Wishing you only the best, boB Stepp From alan.gauld at yahoo.co.uk Tue Jun 2 19:27:24 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 3 Jun 2020 00:27:24 +0100 Subject: [Tutor] Python Networkx with file in gexf format In-Reply-To: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com> References: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com> Message-ID: On 02/06/2020 19:38, Daniel Wobmann wrote: > I'm doing a continuing education, with Python being a relatively large part of it. So are you learning python? Or learning something else in which Python is used? From your message it sounds like the latter? > We are not allowed to use Gephi. Lost me. Never heard of Gephi... > Everything must be analyzed and derived in Python. OK and are they teaching you Python? If not it would seem a tad harsh! > I have a dataset in gexf format Nope! never heard of that either. > about the nodes "students" (student-ID) and "teachers" (teacher-ID), > where each node belongs to a school class and has a corresponding gender;... > The edges connect the pupil-ID by means of "Origin" and "Destination". This all sounds like graph theory. Are you competent in graphs and the associated math? Or is that part of your course? > If someone can help me with this, I would send him/her the dataset by mail. > And of course I would pay something for the work. You can of course make any commercial arrangements you wish but that's not what this list is for. You ask questions about programming/python/the standard library and we answer them. > Now I wish to read out various information from this dataset with > Python and the package networkx Nope, lost me again. Never heard of it. > - and above all to display it graphically. There are several plotting packages in Python. GNUplot is popular. > This causes me many difficulties, because in python I want to work > with the nodes / edges in the gexf document; but also with the values per item It is normal programming practice when dealing with files (of any format) to read them into memory using a data structure best suited to the problem. Modified data can be written back to the files (in the original format) when finished. Its an exercise in frustration to try to process data in a sub-optimal data structure intended for data storage rather than manipulation. > 1. how can I find out from which data type a feature is? How can I > convert the datatype of a feature for example from String to Int (preprocessing engineering)? The usual python approach is to use the int() type conversion. eg int("16") returns the number 16. > 2. how can I calculate the number of edges per node (1 origin and how many targets?)? This is more about the choice of algorithm which is a math question not strictly a Python one. Although the networks package probably has a predefined algorithm you can use, but you should probably ask their support forum about that.It is not part of the standard python library. > 4. develop and display the graph for the whole dataset What does the code for this look like? It will depend on how you choose to store the data. It may also depend on what the networkx package offers. Again a question for their forum. > 5. how can I display graphs, i.e. connections and nodes of a single > school class (clusters?), single nodes (students) of the same class, etc. with different colors?> What does the code for this look like? See 4 above plus the reference to plotting packages... > 6. subgraphs: Are they parts of a whole graph, as I understood it, That sounds like a question for your course tutors. Its what they are there for. > 7. are subgraphs also called "subgroups" and "clusters"? As above. > 8 How can I determine whether or which student is an "influencer" in the class Again this has little to do with python and more to do with your course theory. I suggest you ask the tutors. > 9. how can I remove items. For example, because they represent an outlier? That will depend on the data structures. Probably a networkx thing again. > 10. weight: I have read a lot about it, but I have not been able to figure > out what it is and what purpose it serves. What does this tell me? What can I do with it? Again this is not Python this is your course theory. Ask your tutors, its their job. > 11. How to calculate the following? For example, is this calculated per student ... > - Degree Centrality > - Betweenness-Zentralit?t) > - Closeness Central Office > - Prestige Indegree > - Ego Network Again not python. Ask the tutors. Or even your fellow students? > 12. Link Predictions? I heard that there are ways to use different models (or algorithms?) > to predict what other possible connections between nodes or the students (in our case) might > look like. For example Jaccard, Common Neighbours, Preferential Attachment, > Resource Allocation, etc. What does the code for these look like? These are all more about the math than python. The python code will totally depend on the data structures used. Your networkx package may have some of it pre-coded for you. ask them. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PyTutor at danceswithmice.info Tue Jun 2 20:31:41 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Wed, 3 Jun 2020 12:31:41 +1200 Subject: [Tutor] Practice websites In-Reply-To: References: Message-ID: <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info> On 2/06/20 11:10 PM, Divya wrote: > Please suggest me some websites where I can practice the very basics like > functions, expressions etc.. VISUALIZE CODE AND GET LIVE HELP Learn Python, Java, C, C++, JavaScript, and Ruby Python Tutor (created by Philip Guo) helps people overcome a fundamental barrier to learning programming: understanding what happens as the computer runs each line of code. Write code in your web browser, see it visualized step by step, and get live help from volunteers. Related services: Java Tutor, C Tutor, C++ Tutor, JavaScript Tutor, Ruby Tutor Over ten million people in more than 180 countries have used Python Tutor to visualize over 100 million pieces of code, often as a supplement to textbooks, lectures, and online tutorials... http://pythontutor.com/ -- Regards =dn From cs at cskk.id.au Tue Jun 2 21:23:04 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 3 Jun 2020 11:23:04 +1000 Subject: [Tutor] Named tuple special methods and attributes start with an underscore? In-Reply-To: <20200602231204.GF23247@Dream-Machine1> References: <20200602231204.GF23247@Dream-Machine1> Message-ID: <20200603012304.GA52493@cskk.homeip.net> On 02Jun2020 18:12, boB Stepp wrote: >I was reading an article on the collections library >(https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html). >In it it had the following note: "In Python, methods with leading >underscores are usually considered ?private.? Additional methods provided >by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are >public." This greatly surprised me. So I went to the Python docs >(https://docs.python.org/3/library/collections.html#collections.namedtuple) >and found: "In addition to the methods inherited from tuples, named tuples >support three additional methods and two attributes. To prevent conflicts >with field names, the method and attribute names start with an underscore." >Huh?!? > >The mentioned 5 items are: _make, _asdict, _replace, _fields and >_field_defaults. Of the items "_replace" is the most surprising as that is >already used by Python in other contexts such as str.replace(). These >items don't look to be likely field names to be used by anyone. Any >illumination for this design decision? To my (perhaps naive) eyes this >strikes me as extraordinarily inconsistent Python syntax. By using leading underscores, the user of nametuple is free to use any field names they like as long as they avoid underscores. Don't forget that you can subclass a namedtuple, too. I've got several classes which look like this: class Something(namedtuple('Something', 'a b c')): def some_method(...): ... You're saying I shouldn't be able to have a method called "replace" on my arbitrary class? The _foo thing is only a convention, through _normally_ strongly adhered to. You have the same kind of issue in any shared namespace, and by using _foo for a small number of special but documented methods we leave the way clear for _any_ starts-with-a-letter name to be a field or method of a namedtuple class or subclass. Cheers, Cameron Simpson From robertvstepp at gmail.com Tue Jun 2 22:04:38 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 2 Jun 2020 21:04:38 -0500 Subject: [Tutor] Named tuple special methods and attributes start with an underscore? In-Reply-To: <20200603012304.GA52493@cskk.homeip.net> References: <20200602231204.GF23247@Dream-Machine1> <20200603012304.GA52493@cskk.homeip.net> Message-ID: <20200603020438.GH23247@Dream-Machine1> On Wed, Jun 03, 2020 at 11:23:04AM +1000, Cameron Simpson wrote: >On 02Jun2020 18:12, boB Stepp wrote: >>The mentioned 5 items are: _make, _asdict, _replace, _fields and >>_field_defaults. Of the items "_replace" is the most surprising as that is >>already used by Python in other contexts such as str.replace(). These >>items don't look to be likely field names to be used by anyone. Any >>illumination for this design decision? To my (perhaps naive) eyes this >>strikes me as extraordinarily inconsistent Python syntax. > >By using leading underscores, the user of nametuple is free to use any >field names they like as long as they avoid underscores. Don't forget >that you can subclass a namedtuple, too. I've got several classes >which look like this: > > class Something(namedtuple('Something', 'a b c')): > def some_method(...): ... > >You're saying I shouldn't be able to have a method called "replace" on >my arbitrary class? Then why not str._replace() instead of the current str.replace()? Is it thought that users are less likely to want to modify the string class? Is this the design criteria -- the likeliness of user subclassing? -- Wishing you only the best, boB Stepp From cs at cskk.id.au Wed Jun 3 01:55:59 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 3 Jun 2020 15:55:59 +1000 Subject: [Tutor] Named tuple special methods and attributes start with an underscore? In-Reply-To: <20200603020438.GH23247@Dream-Machine1> References: <20200603020438.GH23247@Dream-Machine1> Message-ID: <20200603055559.GA61937@cskk.homeip.net> On 02Jun2020 21:04, boB Stepp wrote: >On Wed, Jun 03, 2020 at 11:23:04AM +1000, Cameron Simpson wrote: >>By using leading underscores, the user of nametuple is free to use any >>field names they like as long as they avoid underscores. Don't forget >>that you can subclass a namedtuple, too. I've got several classes >>which look like this: >> >> class Something(namedtuple('Something', 'a b c')): >> def some_method(...): ... >> >>You're saying I shouldn't be able to have a method called "replace" >>on my arbitrary class? > >Then why not str._replace() instead of the current str.replace()? Because str is a class with many methods and well defined semantics. namedtuple is essentially an efficient skeleton for a tuple with some fixed field names, and initially _no_ semantics/methods. It is basicly a bare container. Whereas str is a thing with a purpose. >Is it >thought that users are less likely to want to modify the string class? Is >this the design criteria -- the likeliness of user subclassing? It is more that a namedtuple is very basic and has no particular behaviours, maybe like object or SimpleNamespace, etc. It goes out of its way to _not_ pollute the public space with the (small) number of presupplied methods. There is a rule of thumb that one shouldn't subclass builtin types like str, but that is not the criterion here: it is the purpose agnosticness of namedtuple. Let me make a different example. I've got a class which loads CSV or Excel sheets and presumes the first row is a heading row. It reads this, then constructures a namedtuple subclass whose fields are computed from the header names (it does stuff like downcase them and turn whitespace into underscores). Anyway, all the field names commence with letters and might contain anything depending on the comparative sanity of the person supplying the spreadsheet. This is only robust because there are no nametuple starts-iwth-a-letter methods. Cheers, Cameron Simpson From wescpy at gmail.com Wed Jun 3 04:08:16 2020 From: wescpy at gmail.com (wesley chun) Date: Wed, 3 Jun 2020 01:08:16 -0700 Subject: [Tutor] Practice websites In-Reply-To: <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info> References: <69060bdc-41b5-1105-a08d-d825bd4f8a7c@DancesWithMice.info> Message-ID: Hello, this is a very common question and one where you can get many suggestions with a simple online search. I documented a few in my SO answer for a similar question. Cheers, --Wesley On Tue, Jun 2, 2020 at 5:32 PM DL Neil via Tutor wrote: > On 2/06/20 11:10 PM, Divya wrote: > > Please suggest me some websites where I can practice the very basics like > > functions, expressions etc.. > > > VISUALIZE CODE AND GET LIVE HELP > Learn Python, Java, C, C++, JavaScript, and Ruby > Python Tutor (created by Philip Guo) helps people overcome a fundamental > barrier to learning programming: understanding what happens as the > computer runs each line of code. > > Write code in your web browser, see it visualized step by step, and get > live help from volunteers. > > Related services: Java Tutor, C Tutor, C++ Tutor, JavaScript Tutor, > Ruby Tutor > > Over ten million people in more than 180 countries have used Python > Tutor to visualize over 100 million pieces of code, often as a > supplement to textbooks, lectures, and online tutorials... > http://pythontutor.com/ > -- > Regards =dn -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com From mats at wichmann.us Wed Jun 3 14:17:10 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 3 Jun 2020 12:17:10 -0600 Subject: [Tutor] Python Networkx with file in gexf format In-Reply-To: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com> References: <8D2C93FF-A758-4024-98AD-AC7BC7CFB9B1@hotmail.com> Message-ID: <9b2a0480-2a0b-490e-ca58-c22154a4cb3e@wichmann.us> On 6/2/20 12:38 PM, Daniel Wobmann wrote: > Hello everybody, > > I'm doing a continuing education, with Python being a relatively large part of it. With my basic knowledge I have practically no chance - especially for the project work, which we have to deliver on June 20, 2020. We are not allowed to use Gephi. Everything must be analyzed and derived in Python. So I am dependent on help and thank you for every support, no matter how small. > > I have a dataset in gexf format ... > Now I wish to read out various information from this dataset with Python and the package networkx as Alan has pointed out, this is pretty sophisticated stuff. NetworkX is a currently popular package for dealing with network graphs, and it's able to deal in both the older gexf format and the newer graphml format. So all the boxes are ticked. But if you're getting all of this thrown at you at once, that's a big load to swallow. I'm about to delve in a little bit, because of an incoming request on a project I work on, but that door hasn't been opened yet for me. You're unlikely to get much help here, unless one of the contributors happens to be a practitioner; there are thousands upon thousands of Python packages, nobody knows them all. I'd suggest digging around a bit on the NetworkX mailing list, which is a Google Group and thus pretty easily searchable, to see if there are people you can talk to. https://groups.google.com/forum/#!forum/networkx-discuss From robertvstepp at gmail.com Wed Jun 3 23:36:30 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 3 Jun 2020 22:36:30 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: <20200531014208.GA23247@Dream-Machine1> References: <20200531014208.GA23247@Dream-Machine1> Message-ID: I have been continuing to try to understand what is going on. On Sat, May 30, 2020 at 8:42 PM boB Stepp wrote: > > The following function yields type annotation errors and I do not > understand why: > > def evaluate_portfolio( > portfolio: List[Dict[str, Union[str, int, float]]], stock_prices: Dict[str, float] > ) -> Tuple[float, float]: > """Compute the current value and gain/loss of a portfolio.""" > portfolio_value = 0.0 > gain_loss = 0.0 > for stock in portfolio: > current_value = stock["shares"] * stock_prices[stock["name"]] > current_gain_loss = current_value - (stock["shares"] * stock["price"]) > portfolio_value += current_value > gain_loss += current_gain_loss > return portfolio_value, gain_loss > > The error messages generated are: > > report.py|47 col 43 info| Left operand is of type "Union[str, int, float]" > report.py|47 col 43 error| Unsupported operand types for * ("str" and "float") > report.py|47 col 56 error| Invalid index type "Union[str, int, float]" for "Dict[str, float]"; expected type "str" > report.py|48 col 29 info| Both left and right operands are unions > report.py|48 col 29 error| Unsupported operand types for - ("float" and "str") > report.py|48 col 46 error| Unsupported operand types for * ("str" and "str") > report.py|48 col 46 error| Unsupported operand types for * ("str" and "float") > report.py|48 col 46 error| Unsupported operand types for * ("float" and "str") If I simplify the type annotations to: def evaluate_portfolio( portfolio: List[Dict], stock_prices: Dict[str, float] ) -> Tuple[float, float]: """Compute the current value and gain/loss of a portfolio.""" portfolio_value = 0.0 gain_loss = 0.0 for stock in portfolio: current_value = stock["shares"] * stock_prices[stock["name"]] current_gain_loss = current_value - (stock["shares"] * stock["price"]) portfolio_value += current_value gain_loss += current_gain_loss return portfolio_value, gain_loss Then all of the complaints go away. I still do not understand why the more detailed annotations do not give the expected results. I have read and reread the documentation multiple times, but I believe I am doing the annotations correctly. Perhaps there is a nesting limit beyond which mypy chokes? -- boB From robertvstepp at gmail.com Thu Jun 4 00:30:51 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 3 Jun 2020 23:30:51 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: References: <20200531014208.GA23247@Dream-Machine1> Message-ID: As I continue to integrate type annotations with David Beazley's recently released course, "Practical Python Programming", I ran into another issue. I have pared down a larger function to just what seems to be giving the type annotation complaint: def parse_csv(data_rows: List, has_headers: bool = True) -> List: """Parse a CSV file into a list of records.""" data_rows_iter = iter(data_rows) if has_headers: headers = next(data_rows_iter) records = [] for row in data_rows_iter: if has_headers: # Make a dictionary record = dict(zip(headers, row)) else: # Otherwise make a tuple record = tuple(row) records.append(record) return records The complaint is: test.py|19 col 22 error| Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "Dict[Any, Any]") One of the exercises is to return a list of dictionaries if a csv file has headers, but if not to return a list of tuples. mypy apparently does not like this. In the "Type hints cheat sheet..." (at https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) in the section "When you're puzzled or when things are complicated" it discusses the use of "Any": "Use Any if you don't know the type of something or it's too dynamic to write a type for..." This does not seem particularly complicated to me, so I'm probably doing something bad or screwy. Any thoughts? BTW, the above function works. If I run it with: with_headers = [["a", "b", "c"], [1, 2, 3]] without_headers = [[1, 2, 3]] my_dict = parse_csv(with_headers) my_tuple = parse_csv(without_headers, has_headers=False) print("My dict =", my_dict) print() print("My tuple =", my_tuple) I get my expected result: bob at Dream-Machine1:~/practical-python/Work$ python3 test.py My dict = [{'a': 1, 'b': 2, 'c': 3}] My tuple = [(1, 2, 3)] -- boB From __peter__ at web.de Thu Jun 4 04:10:41 2020 From: __peter__ at web.de (Peter Otten) Date: Thu, 04 Jun 2020 10:10:41 +0200 Subject: [Tutor] Type annotation errors References: <20200531014208.GA23247@Dream-Machine1> Message-ID: boB Stepp wrote: > As I continue to integrate type annotations with David Beazley's > recently released course, "Practical Python Programming", I ran into > another issue. I have pared down a larger function to just what seems > to be giving the type annotation complaint: > > def parse_csv(data_rows: List, has_headers: bool = True) -> List: > """Parse a CSV file into a list of records.""" > data_rows_iter = iter(data_rows) > if has_headers: > headers = next(data_rows_iter) > records = [] > for row in data_rows_iter: > if has_headers: > # Make a dictionary > record = dict(zip(headers, row)) > else: > # Otherwise make a tuple > record = tuple(row) > records.append(record) > > return records > > The complaint is: test.py|19 col 22 error| Incompatible types in > assignment (expression has type "Tuple[Any, ...]", variable has type > "Dict[Any, Any]") > > One of the exercises is to return a list of dictionaries if a csv file > has headers, but if not to return a list of tuples. mypy apparently > does not like this. In the "Type hints cheat sheet..." (at > https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) in the > section "When you're puzzled or when things are complicated" it > discusses the use of "Any": > > "Use Any if you don't know the type of something or it's too dynamic > to write a type for..." > > This does not seem particularly complicated to me, so I'm probably > doing something bad or screwy. Any thoughts? Let me note that I do not have any experience with mypy. However, the following > if has_headers: > # Make a dictionary > record = dict(zip(headers, row)) > else: > # Otherwise make a tuple > record = tuple(row) makes every user of classical statically typed languages cringe. What's the type of record after the above? It's either the type of dict(zip(headers, row)) or the type of tuple(row) I don't know if mypy is not smart enough or just refuses to infer the type -- in any case you can help it with a declaration. The most generic would be record: Any but making a union from the types in the error message should work too. record: Union[Tuple[Any, ...], Dict[Any, Any]] You might try to tighten that a bit -- e. g. requiring the dict keys to be strings. There are other things that you may know about the types - all records of one function run will be either tuples or dicts, never a mixture - all iterables in the data_rows list should have the same "length" - the first item in the data_rows list should be an iterable of strings if has_headers is true where I have no idea how it might be explained to a type checker. I fear that a moderately clean typed soluton would require two separate functions parse_csv() parse_csv_with_headers() > BTW, the above function works. Hooray to Python's ducktyping ;) > If I run it with: > > with_headers = [["a", "b", "c"], [1, 2, 3]] > without_headers = [[1, 2, 3]] > > my_dict = parse_csv(with_headers) > my_tuple = parse_csv(without_headers, has_headers=False) > > print("My dict =", my_dict) > print() > print("My tuple =", my_tuple) > > I get my expected result: > > bob at Dream-Machine1:~/practical-python/Work$ python3 test.py > My dict = [{'a': 1, 'b': 2, 'c': 3}] > > My tuple = [(1, 2, 3)] > From __peter__ at web.de Thu Jun 4 09:46:51 2020 From: __peter__ at web.de (Peter Otten) Date: Thu, 04 Jun 2020 15:46:51 +0200 Subject: [Tutor] Type annotation errors References: <20200531014208.GA23247@Dream-Machine1> Message-ID: boB Stepp wrote: One more (remember I'm very new to mypy): > The following function yields type annotation errors and I do not > understand why: > > def evaluate_portfolio( > portfolio: List[Dict[str, Union[str, int, float]]], stock_prices: > Dict[str, float] > ) -> Tuple[float, float]: > """Compute the current value and gain/loss of a portfolio.""" > portfolio_value = 0.0 > gain_loss = 0.0 > for stock in portfolio: > current_value = stock["shares"] * stock_prices[stock["name"]] > current_gain_loss = current_value - (stock["shares"] * > stock["price"]) portfolio_value += current_value > gain_loss += current_gain_loss > return portfolio_value, gain_loss > > The error messages generated are: > > report.py|47 col 43 info| Left operand is of type "Union[str, int, float]" > report.py|47 col 43 error| Unsupported operand types for * ("str" and > "float") Given x: Union[str, int, float] y: float x * y mypy ensures that * is defined for str * float # error int * float # OK float * float # OK There might be a way to tell mypy that two cases cannot occur and still use dicts as pseudo-structs, but I expect that there will be a big impact of optional typing on the design, and unlike unit tests it will not just improve the structure, it will also make the code less flexible. Replacing the somewhat amorphous dict with a dataclass: Money = float # fixme @dataclass class Record: shares: int name: str price: Money def evaluate_portfolio( portfolio: List[Record], stock_prices: Dict[str, Money] ) -> Tuple[float, float]: """Compute the current value and gain/loss of a portfolio.""" portfolio_value = 0.0 gain_loss = 0.0 for stock in portfolio: current_value = stock.shares * stock_prices[stock.name] current_gain_loss = current_value - stock.shares * stock.price portfolio_value += current_value gain_loss += current_gain_loss return portfolio_value, gain_loss PS: In spite of my defeatist remark above I prefer this version over the one you posted; maybe not all is lost in Python land ;) PPS: For someone who knows a little C the obvious fix for your version is to cast the union to the expected type: for stock in portfolio: shares = cast(int, stock["shares"]) name = cast(str, stock["name"]) price = cast(float, stock["price"]) current_value = shares * stock_prices[name] current_gain_loss = current_value - shares * price portfolio_value += current_value gain_loss += current_gain_loss > report.py|47 col 56 error| Invalid index type "Union[str, int, > float]" for "Dict[str, float]"; expected type "str" report.py|48 col 29 > info| Both left and right operands are unions report.py|48 col 29 error| > Unsupported operand types for - ("float" and "str") report.py|48 col 46 > error| Unsupported operand types for * ("str" and "str") report.py|48 col > 46 error| Unsupported operand types for * ("str" and "float") report.py|48 > col 46 error| Unsupported operand types for * ("float" and "str") > > For reference line 47 is the line in the for loop beginning > "current_value..." > > portfolio is a list of dictionaries where each dictionary is of the form > {"name": "stock name", "shares": number_of_shares_owned, "price": > price_per_share} > > The code runs flawlessly and gives the expected results. Where am I going > wrong in my type annotations? > From __peter__ at web.de Thu Jun 4 10:31:24 2020 From: __peter__ at web.de (Peter Otten) Date: Thu, 04 Jun 2020 16:31:24 +0200 Subject: [Tutor] Type annotation errors References: <20200531014208.GA23247@Dream-Machine1> Message-ID: Peter Otten wrote: > There might be a way to tell mypy that two cases cannot occur and still > use dicts as pseudo-structs I found https://mypy.readthedocs.io/en/stable/more_types.html#typeddict with that: from typing_extensions import TypedDict Record = TypedDict("Record", {"shares": int, "name": str, "price": float}) def evaluate_portfolio( portfolio: List[Record], stock_prices: Dict[str, float] ) -> Tuple[float, float]: ... # body unchanged From mats at wichmann.us Thu Jun 4 11:32:39 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 4 Jun 2020 09:32:39 -0600 Subject: [Tutor] Type annotation errors In-Reply-To: References: <20200531014208.GA23247@Dream-Machine1> Message-ID: <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us> On 6/3/20 10:30 PM, boB Stepp wrote: > As I continue to integrate type annotations with David Beazley's > recently released course, "Practical Python Programming", I ran into > another issue. I have pared down a larger function to just what seems > to be giving the type annotation complaint: > > def parse_csv(data_rows: List, has_headers: bool = True) -> List: > """Parse a CSV file into a list of records.""" > data_rows_iter = iter(data_rows) > if has_headers: > headers = next(data_rows_iter) > records = [] > for row in data_rows_iter: > if has_headers: > # Make a dictionary > record = dict(zip(headers, row)) > else: > # Otherwise make a tuple > record = tuple(row) > records.append(record) > > return records > > The complaint is: test.py|19 col 22 error| Incompatible types in > assignment (expression has type "Tuple[Any, ...]", variable has type > "Dict[Any, Any]") > > One of the exercises is to return a list of dictionaries if a csv file > has headers, but if not to return a list of tuples. mypy apparently > does not like this. I don't like it either :) (I know, who am I to criticize dabeaz - even if I did so professionally for a very short period as one of his technical editors on Python Essential Reference 2:e way back in 2000). Functions/methods that return different types under different calling scenarios are certainly possible in Python, but that doesn't mean it's a great idea for usability. A contrived learning example is fine; In Real Life, I don't see why on earth you'd want this awkward setup. So worrying too much about twisting typing so mypy is happy about this doesn't seem terribly worthwhile... just sayin'. From robertvstepp at gmail.com Thu Jun 4 14:01:42 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 4 Jun 2020 13:01:42 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: References: <20200531014208.GA23247@Dream-Machine1> Message-ID: <20200604180142.GI23247@Dream-Machine1> Ah, Peter, you gave me the pieces I needed to put it all together (I think.). On Thu, Jun 04, 2020 at 10:10:41AM +0200, Peter Otten wrote: >boB Stepp wrote: > >> ...I have pared down a larger function to just what seems >> to be giving the type annotation complaint: >> >> def parse_csv(data_rows: List, has_headers: bool = True) -> List: >> """Parse a CSV file into a list of records.""" >> data_rows_iter = iter(data_rows) >> if has_headers: >> headers = next(data_rows_iter) >> records = [] >> for row in data_rows_iter: >> if has_headers: >> # Make a dictionary >> record = dict(zip(headers, row)) >> else: >> # Otherwise make a tuple >> record = tuple(row) >> records.append(record) >> >> return records >> >> The complaint is: test.py|19 col 22 error| Incompatible types in >> assignment (expression has type "Tuple[Any, ...]", variable has type >> "Dict[Any, Any]") >Let me note that I do not have any experience with mypy. >However, the following > >> if has_headers: >> # Make a dictionary >> record = dict(zip(headers, row)) >> else: >> # Otherwise make a tuple >> record = tuple(row) > >makes every user of classical statically typed languages cringe. >What's the type of record after the above? It's either the type of > >dict(zip(headers, row)) > >or the type of > >tuple(row) > >I don't know if mypy is not smart enough or just refuses to infer the type >-- in any case you can help it with a declaration. >The most generic would be > >record: Any > >but making a union from the types in the error message should work too. > >record: Union[Tuple[Any, ...], Dict[Any, Any]] This is the key bit that made it all come together for me. I had annotated the function's parameters and its return types, but did not try to "help" mypy with declaring one of the intermediate identifiers. And you caused me to remember that I am allowed to declare types of identifiers without assignment. I added the following just after my function's docstring and it resolved the issue: record: Union[Tuple[Any, ...], Dict[str, Any]] >There are other things that you may know about the types > >- all records of one function run will be either tuples or dicts, never a > mixture >- all iterables in the data_rows list should have the same "length" >- the first item in the data_rows list should be an iterable of strings if > has_headers is true > >where I have no idea how it might be explained to a type checker. I fear >that a moderately clean typed soluton would require two separate functions > >parse_csv() >parse_csv_with_headers() The points you list above are ones I have already given some thought to, wondering if I should build in some checks. But as the "real problem" I am working with is part of a series of exercises I am waiting to see where Beasley is taking this. So far he has been using an incremental approach "improving" the ever growing and morphing program(s) as he introduces more Python. Beasley mentioned type annotations very briefly, but I have been applying them throughout the course as that is one of my current points of learning that I have set for myself. >> BTW, the above function works. > >Hooray to Python's ducktyping ;) Amen! -- Wishing you only the best, boB Stepp From robertvstepp at gmail.com Thu Jun 4 14:14:45 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 4 Jun 2020 13:14:45 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us> References: <20200531014208.GA23247@Dream-Machine1> <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us> Message-ID: <20200604181445.GJ23247@Dream-Machine1> On Thu, Jun 04, 2020 at 09:32:39AM -0600, Mats Wichmann wrote: >On 6/3/20 10:30 PM, boB Stepp wrote: >> One of the exercises is to return a list of dictionaries if a csv file >> has headers, but if not to return a list of tuples. mypy apparently >> does not like this. > >I don't like it either :) (I know, who am I to criticize dabeaz - even >if I did so professionally for a very short period as one of his >technical editors on Python Essential Reference 2:e way back in 2000). The actual set of exercises is from "3.2 Moe on Functions" at https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/02_More_functions.html In this exercise set he wishes to create a module fileparse which can accept a csv-like file and allow one to obtain a list of dictionaries (one per file row) if the file has headers or a list of tuples if not, representing the collection of records. Additionally he wishes to allow for setting arguments to choose only certain data columns (If the file has headers), do type conversions by providing a list of functions to do the conversions, and setting a different delimiter than the default comma. At the end of the exercises he comments: "If you?ve made it this far, you?ve created a nice library function that?s genuinely useful. You can use it to parse arbitrary CSV files, select out columns of interest, perform type conversions, without having to worry too much about the inner workings of files or the csv module." >Functions/methods that return different types under different calling >scenarios are certainly possible in Python, but that doesn't mean it's >a great idea for usability. A contrived learning example is fine; In >Real Life, I don't see why on earth you'd want this awkward setup. So >worrying too much about twisting typing so mypy is happy about this >doesn't seem terribly worthwhile... just sayin'. However, I have to say, the end result *does* seem useful! -- Wishing you only the best, boB Stepp From alan.gauld at yahoo.co.uk Thu Jun 4 19:07:55 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 5 Jun 2020 00:07:55 +0100 Subject: [Tutor] Type annotation errors In-Reply-To: <20200604181445.GJ23247@Dream-Machine1> References: <20200531014208.GA23247@Dream-Machine1> <5bfd171d-259b-d2ab-e910-e519020dd6ee@wichmann.us> <20200604181445.GJ23247@Dream-Machine1> Message-ID: On 04/06/2020 19:14, boB Stepp wrote: > In this exercise set he wishes to create a module fileparse which can > accept a csv-like file and allow one to obtain a list of dictionaries (one > per file row) if the file has headers or a list of tuples if not, > representing the collection of records. But is that really useful? If you don;t know if the file has headers or not you have to examine the type of the result to find out. If you do know in advance you can just have two separate functions. And if you don't know if it has headers why not create a function that examines the file before parsing so you can write if hasHeaders(file): parseHeaderFile(file) else: parseNoHeaders(file) Then you know what type of result you get. Better to check the state of the data than try to derive types afterwards. Functions that try to handle two different types of input by returning two different types of output are really just two functions bound in one. (Different if you can return a single data type for two inputs) I don't know the book so maybe he is heading towards a single unified object model with polymorphic methods so that you can treat the two results as a single ParseResult object. It is certainly possible to create a polymorphic solution, but it is a lot of work. But otherwise I'd say it's a bad design that inevitably leads to maintenance headaches. > Additionally he wishes to allow > for setting arguments to choose only certain data columns (If the file has > headers), do type conversions by providing a list of functions to do the > conversions, and setting a different delimiter than the default comma. At > the end of the exercises he comments: > > "If you?ve made it this far, you?ve created a nice library function that?s > genuinely useful. You can use it to parse arbitrary CSV files, select out > columns of interest, perform type conversions, without having to worry too > much about the inner workings of files or the csv module." Sorry, but it sounds like it should be a library of functions. That is one function overloaded way too far. Maintaining it will be a nightmare. Imagine the number of regression tests required for even a minor change! I know we can automate them but it's still a sign of a design anti-pattern. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Thu Jun 4 20:34:36 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 4 Jun 2020 19:34:36 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: References: <20200531014208.GA23247@Dream-Machine1> Message-ID: <20200605003436.GK23247@Dream-Machine1> On Thu, Jun 04, 2020 at 03:46:51PM +0200, Peter Otten wrote: >boB Stepp wrote: >There might be a way to tell mypy that two cases cannot occur and still use >dicts as pseudo-structs, but I expect that there will be a big impact of >optional typing on the design, and unlike unit tests it will not just >improve the structure, it will also make the code less flexible. >Replacing the somewhat amorphous dict with a dataclass: > >Money = float # fixme > >@dataclass >class Record: > shares: int > name: str > price: Money > > >def evaluate_portfolio( > portfolio: List[Record], > stock_prices: Dict[str, Money] >) -> Tuple[float, float]: > """Compute the current value and gain/loss of a portfolio.""" > portfolio_value = 0.0 > gain_loss = 0.0 > for stock in portfolio: > current_value = stock.shares * stock_prices[stock.name] > current_gain_loss = current_value - stock.shares * stock.price > portfolio_value += current_value > gain_loss += current_gain_loss > return portfolio_value, gain_loss > >PS: In spite of my defeatist remark above I prefer this version over the one >you posted; maybe not all is lost in Python land ;) In terms of following along with Beazley's course material this would be cheating. Classes have not been presented yet. Even very simple ones. ~(:>)) >PPS: For someone who knows a little C the obvious fix for your version is to >cast the union to the expected type: > > for stock in portfolio: > shares = cast(int, stock["shares"]) > name = cast(str, stock["name"]) > price = cast(float, stock["price"]) > > current_value = shares * stock_prices[name] > current_gain_loss = current_value - shares * price > portfolio_value += current_value > gain_loss += current_gain_loss I saw cast() in the mypy documentation, but had hopes that the problem was me and my lack of understanding. -- Wishing you only the best, boB Stepp From robertvstepp at gmail.com Thu Jun 4 20:41:52 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 4 Jun 2020 19:41:52 -0500 Subject: [Tutor] Type annotation errors In-Reply-To: References: <20200531014208.GA23247@Dream-Machine1> Message-ID: <20200605004152.GL23247@Dream-Machine1> On Thu, Jun 04, 2020 at 04:31:24PM +0200, Peter Otten wrote: >Peter Otten wrote: > >> There might be a way to tell mypy that two cases cannot occur and still >> use dicts as pseudo-structs > >I found > >https://mypy.readthedocs.io/en/stable/more_types.html#typeddict > >with that: > >from typing_extensions import TypedDict > >Record = TypedDict("Record", {"shares": int, "name": str, "price": float}) > >def evaluate_portfolio( > portfolio: List[Record], stock_prices: Dict[str, float] >) -> Tuple[float, float]: > ... # body unchanged Hmm. This seems to be the exactly what the situation requires. I had not looked into typing_extensions yet. Thanks! -- Wishing you only the best, boB Stepp From PyTutor at danceswithmice.info Fri Jun 5 05:13:40 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Fri, 5 Jun 2020 21:13:40 +1200 Subject: [Tutor] Type annotation errors In-Reply-To: <20200605003436.GK23247@Dream-Machine1> References: <20200531014208.GA23247@Dream-Machine1> <20200605003436.GK23247@Dream-Machine1> Message-ID: <55169a4d-28e6-07d9-bafc-6d870647ad50@DancesWithMice.info> > In terms of following along with Beazley's course material this would be > cheating.? Classes have not been presented yet.? Even very simple ones. > ~(:>)) > >> PPS: For someone who knows a little C the obvious fix for your version >> is to >> cast the union to the expected type: This is a little difficult to rationalise: - we are not trying to get ahead of the course material - but we are prepared to launch into complex (if not complicated) mypy Apologies, I can see the 'why' but can't help but feel it is only that imbalance which has led to the problem... I'd like to discuss the (actual) problem, and then dispute the claim-pursuant: [from another part of the thread] <<< In this exercise set he wishes to create a module fileparse which can accept a csv-like file and allow one to obtain a list of dictionaries (one per file row) if the file has headers or a list of tuples if not, representing the collection of records. Additionally he wishes to allow for setting arguments to choose only certain data columns (If the file has headers), do type conversions by providing a list of functions to do the conversions, and setting a different delimiter than the default comma. At the end of the exercises he comments: "If you?ve made it this far, you?ve created a nice library function that?s genuinely useful. You can use it to parse arbitrary CSV files, select out columns of interest, perform type conversions, without having to worry too much about the inner workings of files or the csv module." >>> I'm firmly joining with others who have suggested that rather than "nice" it is actually quite 'ugly'. The routine, as-is, violates the Single Responsibility Principle (SRP). It is trying to deal with CSV files that have column headings AND those which don't. That's not an horrendous crime, per-se (but see later). However, the idea that the routine will output either a list of dicts or a list of tuples, most certainly is a major transgression! The Zen of Python says "Simple is better than complex. Complex is better than complicated.". Which of the three describes that code? To be fair, you weren't intending to discuss the course materials/output, and IIRC there has been no explanation as to how the calling routine 'knows' whether this .CSV has headers or not. Similarly, it does not say how it will deal with the two-format output issue when it comes time to actually use the extracted-data. Regarding the first, wouldn't it make sense to not only ascertain that headers are present (or not) AND note any headings - as a single task? Now, instead of varying the function's output according to the presence of headers (or not), the data could be extracted (only) as a tuple. Lastly, when it comes time to further-process the extracted-data, it can be paired/zipped with the headings, if-possible, as-required... Alternately, write the basic function (no headings) and then add a decorator to handle headings - separation in a different fashion. To those, apply the Zen? Now apply mypy to the function (even design-level stubs)? Per the comment "nice library function", I'm hoping that you will later report that the course builds-upon this/these function(s) and makes them even more useful/"nice". Speaking for myself, and because I have frequent needs to extract data from worksheets or .CSV files, I have a bunch of classes ready for re-use (sub-classing per file/application) and find them *very* useful. As a general rule, I find that the greatest re-use is of simple classes rather than those more complex or complicated. The complexity comes when the simple 'framework' of a base-class is adapted and expanded to suit the application. So, SRP rules! It might be a little early to throw at you what is possibly the hardest part of "SOLID" to understand and implement by-habit (but I know you've used multiple languages over the years, before tackling Python): the Dependency Inversion Principle (DIP) wherein we say that "details should depend on abstractions" not "abstractions depend upon details". In this mode, we abstract the process of taking data from a worksheet. Then, isn't the absence/presence of headings, a 'detail'? (just as another hint for the course's future: that we might only wish to extract specific columns ("select") or rows ("project")...) Each of these 'details' refines the extraction process rather than calls for an entirely different method of extraction/different presentation of the results! -- Regards =dn From nihal.shiva007 at gmail.com Fri Jun 5 02:39:37 2020 From: nihal.shiva007 at gmail.com (Nihal shivakumar) Date: Fri, 5 Jun 2020 12:09:37 +0530 Subject: [Tutor] Tutor Digest, Vol 196, Issue 1 In-Reply-To: References: Message-ID: Use website coursera Make account and learn audit the courses Learn from many university and google as well On Wed 3 Jun, 2020, 4:42 AM , wrote: > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > Today's Topics: > > 1. Python Networkx with file in gexf format (Daniel Wobmann) > 2. Practice websites (Divya) > 3. Re: Practice websites (Alan Gauld) > 4. Named tuple special methods and attributes start with an > underscore? (boB Stepp) > > > > ---------- Forwarded message ---------- > From: Daniel Wobmann > To: "tutor at python.org" > Cc: > Bcc: > Date: Tue, 2 Jun 2020 18:38:36 +0000 > Subject: [Tutor] Python Networkx with file in gexf format > Hello everybody, > > I'm doing a continuing education, with Python being a relatively large > part of it. With my basic knowledge I have practically no chance - > especially for the project work, which we have to deliver on June 20, 2020. > We are not allowed to use Gephi. Everything must be analyzed and derived in > Python. So I am dependent on help and thank you for every support, no > matter how small. > > I have a dataset in gexf format about the nodes "students" (student-ID) > and "teachers" (teacher-ID), where each node belongs to a school class and > has a corresponding gender; for teachers no gender is given. There are 10 > school classes, e.g. 1A, 2B, etc. > The edges connect the pupil-ID by means of "Origin" and "Destination". The > edges are all of the type "Undirected" and weight "1". The "duration" is > the duration of all interactions between the nodes (origin and > destination); "count" is the number of times the origin and destination > have joined together to form an interaction. I have attached the dataset to > you. > > If someone can help me with this, I would send him/her the dataset by > mail. And of course I would pay something for the work. > > So far I have managed to get the system to tell me how many nodes and > edges there are and what the average degree per node is. That was it. > > Now I wish to read out various information from this dataset with Python > and the package networkx - and above all to display it graphically. This > causes me many difficulties, because in python I want to work with the > nodes / edges in the gexf document; but also with the values per item - for > example with the value of an ID of a student or with a class name. For this > I want to use "networkx". And these are my questions: > > 1. how can I find out from which data type a feature is? How can I convert > the datatype of a feature for example from String to Int (preprocessing > engineering)? > > 2. how can I calculate the number of edges per node (1 origin and how many > targets?)? I think this is called "degree", I have seen. What does this > code look like? So I want to know how many connections (edges) the node > 1551 has to other nodes, for example how many connections the student 1551 > has to other students to other students (and teachers). How can I list them > per node? What does the code for this look like? > For example, how can I calculate the sum of "counts" or "duration" per > student ID? How can I use the result of the number of nodes per Student ID > to divide them, for example to calculate the average duration? > > 4. develop and display the graph for the whole dataset What does the code > for this look like? > > 5. how can I display graphs, i.e. connections and nodes of a single school > class (clusters?), single nodes (students) of the same class, etc. with > different colors? What does the code for this look like? > > 6. subgraphs: Are they parts of a whole graph, as I understood it, or? How > can I display them for example for between two, three classes, ten students > per class, for students and teachers together, etc.? Or for example for the > connections within a class? What does the code for this look like? > > 7. are subgraphs also called "subgroups" and "clusters"? What does the > code for this look like so that I can graphically represent such > properties? What do I concentrate on in the dataset? For example items? > values? > > 8 How can I determine whether or which student is an "influencer" in the > class and which student is not an influencer at all? And which pupil is the > "influencer" between school classes? Which are the "inluencers" between > school classes? What does the code for this look like? > > 9. how can I remove items. For example, because they represent an outlier? > Or simply remove all those items whose "count" is below 10, for example? > What does the code for this look like? > > 10. weight: I have read a lot about it, but I have not been able to figure > out what it is and what purpose it serves. What does this tell me? What can > I do with it? How can I change this weight? Why is the weight adjusted in > different ways, i.e. for certain connections the weight is often set to 2, > for others to 3, etc. And above all: Why should I change a weight, i.e. > what could be the intention? What would this mean for "my" dataset? Between > all origins and destinations, in our case there is weight 1. Why should I > change it? > Why should it make sense to change weights? In which case would I do this > and why? What is the code for changing the weight? > > 11. How to calculate the following? For example, is this calculated per > student or even per cluster (e.g. school class)? Or for which properties is > this calculated? > - Degree Centrality > - Betweenness-Zentralit?t) > - Closeness Central Office > - Prestige Indegree > - Ego Network > > 12. Link Predictions? I heard that there are ways to use different models > (or algorithms?) to predict what other possible connections between nodes > or the students (in our case) might look like. For example Jaccard, Common > Neighbours, Preferential Attachment, Resource Allocation, etc. What does > the code for these look like? > > I am looking forward to your feedback. Thank you very much and best regards > > Daniel Wobmann > > > > > > > > > > > > > ---------- Forwarded message ---------- > From: Divya > To: tutor at python.org > Cc: > Bcc: > Date: Tue, 2 Jun 2020 16:40:56 +0530 > Subject: [Tutor] Practice websites > Please suggest me some websites where I can practice the very basics like > functions, expressions etc.. > > > > > ---------- Forwarded message ---------- > From: Alan Gauld > To: tutor at python.org > Cc: > Bcc: > Date: Wed, 3 Jun 2020 00:00:05 +0100 > Subject: Re: [Tutor] Practice websites > On 02/06/2020 12:10, Divya wrote: > > Please suggest me some websites where I can practice the very basics like > > functions, expressions etc.. > > > I'm not sure what you are looking for. > > There are a couple of web sites with virtual Python interpreters > where you can type basic Python code and it will execute it > for you. If that's what you want here is one I found. I > don't use this service so can't say how good it is but it > seems to handle print("hello") ok...! > > https://repl.it/languages/Python3 > > But most folks find it easier to download Python to their PC > (Or tablet) and use it offline. Especially if you want to process > local data or manipulate you machine in some way. > > If on the other hand you are looking for tutorial information there > is a whole page for beginners (one each both non-programmers and > existing programmers in other languages). (Or you can try > mine - see the link in my .sig > > Finally, if you want projects or exercises there are some sites > that do that too - I think coursera has some. And the Python > Challenge website is an interesting way to learn new tricks > with Python. > > I hope that helps, if not you need to be a bit more specific > about what you are after. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > > > > ---------- Forwarded message ---------- > From: boB Stepp > To: tutor at python.org > Cc: > Bcc: > Date: Tue, 2 Jun 2020 18:12:04 -0500 > Subject: [Tutor] Named tuple special methods and attributes start with an > underscore? > I was reading an article on the collections library > ( > https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html > ). > In it it had the following note: "In Python, methods with leading > underscores are usually considered ?private.? Additional methods provided > by namedtuple (like _asdict(), ._make(), ._replace(), etc.), however, are > public." This greatly surprised me. So I went to the Python docs > (https://docs.python.org/3/library/collections.html#collections.namedtuple > ) > and found: "In addition to the methods inherited from tuples, named tuples > support three additional methods and two attributes. To prevent conflicts > with field names, the method and attribute names start with an underscore." > Huh?!? > > The mentioned 5 items are: _make, _asdict, _replace, _fields and > _field_defaults. Of the items "_replace" is the most surprising as that is > already used by Python in other contexts such as str.replace(). These > items don't look to be likely field names to be used by anyone. Any > illumination for this design decision? To my (perhaps naive) eyes this > strikes me as extraordinarily inconsistent Python syntax. > > -- > Wishing you only the best, > > boB Stepp > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > From robertvstepp at gmail.com Fri Jun 5 21:40:15 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 5 Jun 2020 20:40:15 -0500 Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type annotation errors) Message-ID: <20200606014015.GQ23247@Dream-Machine1> Don't know why, but dn's email did not arrive in my inbox. I am beginning to believe that Gmail applies random filtering to writers from UK, NZ, Australia, etc. So I've copied and pasted from the Tutor Archives. DL Neil wrote: > boB wrote: >> Peter wrote: >> In terms of following along with Beazley's course material this would be >> cheating. Classes have not been presented yet. Even very simple ones. >> ~(:>)) >> >>> PPS: For someone who knows a little C the obvious fix for your version >>> is to >>> cast the union to the expected type: >This is a little difficult to rationalise: >- we are not trying to get ahead of the course material >- but we are prepared to launch into complex (if not complicated) mypy >Apologies, I can see the 'why' but can't help but feel it is only that >imbalance which has led to the problem... HALT! *I* am solely responsible for mixing in type annotations, not Mr. Beazley. As you know I have been working on learning these. While I am working through his course I am practicing type annotations. Beazley does briefly mention type annotations, but so far he has not asked the reader of his course to do anything with them. Any resulting messy annotations are the sole responsibility of daboB (*not* dabeaz). >I'd like to discuss the (actual) problem, and then dispute the >claim-pursuant: >[from another part of the thread] ><<< >In this exercise set he wishes to create a module fileparse which can >accept a csv-like file and allow one to obtain a list of dictionaries (one >per file row) if the file has headers or a list of tuples if not, >representing the collection of records. Additionally he wishes to allow >for setting arguments to choose only certain data columns (If the file has >headers), do type conversions by providing a list of functions to do the >conversions, and setting a different delimiter than the default comma. At >the end of the exercises he comments: >"If you?ve made it this far, you?ve created a nice library function that?s >genuinely useful. You can use it to parse arbitrary CSV files, select out >columns of interest, perform type conversions, without having to worry too >much about the inner workings of files or the csv module." > >>> >I'm firmly joining with others who have suggested that rather than >"nice" it is actually quite 'ugly'. The routine, as-is, violates the >Single Responsibility Principle (SRP). It is trying to deal with CSV >files that have column headings AND those which don't. That's not an >horrendous crime, per-se (but see later). However, the idea that the >routine will output either a list of dicts or a list of tuples, most >certainly is a major transgression! Bear in mind that as I have been working my way through the material Beazley has been gradually adding in more Python and having the reader make modifications to already existing code that the reader has written. To my eyes, he has gradually been tightening up the code and making it more realistic. For the current function exercise that is taking quite a beating in this forum I will report the next segment of the story. I am now in "3.3 Error Checking" (https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/03_Error_checking.html). In "Exercise 3.8: Raising exceptions" he says: "The parse_csv() function you wrote in the last section allows user-specified columns to be selected, but that only works if the input data file has column headers. Modify the code so that an exception gets raised if both the select and has_headers=False arguments are passed. For example: >>> parse_csv('Data/prices.csv', select=['name','price'], >>> has_headers=False) Traceback (most recent call last): File "", line 1, in File "fileparse.py", line 9, in parse_csv raise RuntimeError("select argument requires column headers") RuntimeError: select argument requires column headers >>> " I had wondered about this point as well as some others and was curious whether he would address it later. So, typically for the course so far, he gets around to addressing this particular item. It would not surprise me at all if the parse_csv module eventually morphs into something less likely to raise Tutor hackles. I will keep you posted! -- Wishing you only the best, boB Stepp From 1611kjb at gmail.com Fri Jun 5 20:19:25 2020 From: 1611kjb at gmail.com (1611kjb at gmail.com) Date: Fri, 5 Jun 2020 20:19:25 -0400 Subject: [Tutor] Beginner Noob Message-ID: <023d01d63b98$22f22290$68d667b0$@gmail.com> I am very green with Python. In fact, Hello World is it so far. I'm reading/learning from a book called Python Programming for the Absolute Beginner. My first question is real simple, looking at the UI and reading the beginning pages, Python seems to follow in the steps of Visual Basic. BASIC was written in the 1960's and I first ran into it in 1983 on a VIC20 computer, where I also bought a stand alone a cartridge and learned about machine language. In any event, when it started, BASIC was an interpreted language. You couldn't run a program stand alone. You had to buy an interpreter, then create a numbered, formatted ASCII text file which the interpreter read and executed line by line. Eventually Microsoft created Visual Basic with a graphical UI and a runtime package and now you can do most things in VB if you like. Python seems to be running this same gauntlet. I can run/test it through a Python Interpreter or it can be compiled into a runtime. At the moment I am learning using the Python 3.8.3 shell from the Microsoft Store and I have installed the Python branch to Visual Studio Community Edition. Whew, I'm long winded, I say all that to ask, what are the advantages to jumping over to Python from VB? I am simultaneously working on C# and wondering if it's worth taxing myself to learn another language. I started it because I am working with Mindstorms EV3 robotics kits, there educational platform for K12 education, Arduino controllers and Raspberry PI computers. They all seem to like Python and C, C++ and C#. I'm an old retired guy stretching the grey muscles and just wondering if this is a good way to apply myself. Thanks for any input. I'm sure I'll br here a lot. ---Mike From jf_byrnes at comcast.net Fri Jun 5 21:01:14 2020 From: jf_byrnes at comcast.net (Jim) Date: Fri, 5 Jun 2020 20:01:14 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing Message-ID: Mint18.3, python3.6, pandas 0.24.1 et_file = '/home/jfb/Downloads/PortfolioDownload.csv' df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, engine='python') df.to_clipboard(sep=',') print(df) Manual notes the following. I'm not using PyQt4, but xclip is installed. Notes: Requirements for your platform. Linux : xclip, or xsel (with PyQt4 modules) Windows : none OS X : none The print command prints what I expect to see. I don't use pandas that much so maybe I am missing something. Thanks, Jim From manpritsinghece at gmail.com Sat Jun 6 00:11:19 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sat, 6 Jun 2020 09:41:19 +0530 Subject: [Tutor] Question regarding use of assignment expression in python 3.8.3 Message-ID: Dear all, According to Heron's formula for finding area of a triangle , if the sides of a triangle are a, b & c is : s = (a+b+c) / 2 area =sqrt( s * (s-a) * (s-b) * (s-c)) // sqrt means square root so for finding the area of the triangle using Heron's formula in Python , if i write code like this , will it be a valid practise ? I have used assignment expression while calculating the area a = int(input("Enter value of first side")) // Assuming value is integer b = int(input("Enter value of second side")) // Assuming value is integer c = int(input("Enter value of third side")) // Assuming value is integer area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5 print("Area of the triangle is", area) Regards Manprit Singh From alan.gauld at yahoo.co.uk Sat Jun 6 03:39:39 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 6 Jun 2020 08:39:39 +0100 Subject: [Tutor] Question regarding use of assignment expression in python 3.8.3 In-Reply-To: References: Message-ID: On 06/06/2020 05:11, Manprit Singh wrote: > so for finding the area of the triangle using Heron's formula in Python , > if i write code like this , will it be a valid practise ? Yes, if you just want to practice use of assignment expressions. > area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5 Its syntactically valid to use it here but offers very no advantage over a separate assignment line s = a+b+c And has 2 minor disadvantages: 1) its more typing (2 keystrokes) 2) its harder to debug - no way to inspect s prior to executing the calculation. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sat Jun 6 03:58:56 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 6 Jun 2020 08:58:56 +0100 Subject: [Tutor] Beginner Noob In-Reply-To: <023d01d63b98$22f22290$68d667b0$@gmail.com> References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: On 06/06/2020 01:19, 1611kjb at gmail.com wrote: > Whew, I'm long winded, I say all that to ask, what are the advantages to > jumping over to Python from VB? Python is a more modern language with more powerful data structures and language constructs. Although with modern VB.Net that's less of an argument. Python also has an awesome standard library and third-party supported ecosystem. > I am simultaneously working on C# and > wondering if it's worth taxing myself to learn another language. Every language teaches lessons that you can apply in every other language. Some teach more than others - Lisp, Smalltalk, Prolog, etc C# is a traditional language in the same vein as C/C++/Pascal/Java. It's very good for large projects (100k+ lines) involving many programmers. But it requires a lot of planning and design at a detailed level to use effectively. Python is designed for rapid implementation. It's not as fast in execution but it can be thrown together in a more experimental fashion. Before I retired I used Python as a prototyping language before handing designs over to our contractor programmers who were using Java. Of course Python can be used in production code too with a little extra care. VB sits somewhere between those two on the technology continuum Faster to write than C#, not as fast as Python(unless you are building GUIs) but not as powerful as C# either. (I may be wrong but I get the impression that VB.Net is slowly fading away. C# has closed the gap to the point where VB's advantages have been eroded.) > platform for K12 education, Arduino controllers and Raspberry PI computers. > They all seem to like Python and C, C++ and C#. I'm an old retired guy > stretching the grey muscles and just wondering if this is a good way to > apply myself. Thanks for any input. I'm sure I'll br here a lot. Python is used in all these areas and is generally considered easier to learn than C# and certainly C++. I would only recommend C++ if you are tinkering at the machine level - its the natural partner for an Arduino for example. C# (and Java) are similar to C++ but more focused on higher level application code. C++ compiles to native machine code. All the others compile to bytecode which is then interpreted. For normal human interactive programs it makes little difference on modern computers. If you are writing a high data volume server or a piece of hardware interface then speed may become an issue and c++ wins. But at the expense of much harder to write, test and debug code. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PyTutor at danceswithmice.info Sat Jun 6 04:38:15 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sat, 6 Jun 2020 20:38:15 +1200 Subject: [Tutor] Beginner Noob In-Reply-To: <023d01d63b98$22f22290$68d667b0$@gmail.com> References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: On 6/06/20 12:19 PM, 1611kjb at gmail.com wrote: > I am very green with Python. In fact, Hello World is it so far. I'm > reading/learning from a book called Python Programming for the Absolute > Beginner. My first question is real simple, looking at the UI and reading > the beginning pages, Python seems to follow in the steps of Visual Basic. > BASIC was written in the 1960's and I first ran into it in 1983 on a VIC20 > computer, where I also bought a stand alone a cartridge and learned about > machine language. In any event, when it started, BASIC was an interpreted > language. You couldn't run a program stand alone. You had to buy an > interpreter, then create a numbered, formatted ASCII text file which the > interpreter read and executed line by line. Eventually Microsoft created > Visual Basic with a graphical UI and a runtime package and now you can do > most things in VB if you like. Python seems to be running this same > gauntlet. I can run/test it through a Python Interpreter or it can be > compiled into a runtime. At the moment I am learning using the Python 3.8.3 > shell from the Microsoft Store and I have installed the Python branch to > Visual Studio Community Edition. > > > > Whew, I'm long winded, I say all that to ask, what are the advantages to > jumping over to Python from VB? I am simultaneously working on C# and > wondering if it's worth taxing myself to learn another language. I started > it because I am working with Mindstorms EV3 robotics kits, there educational > platform for K12 education, Arduino controllers and Raspberry PI computers. > They all seem to like Python and C, C++ and C#. I'm an old retired guy > stretching the grey muscles and just wondering if this is a good way to > apply myself. Thanks for any input. I'm sure I'll br here a lot. Further to Alan's comments:- (I often cast myself as offering a contrary view to his - fortunately we live far-enough apart that he can't toss his caber at me. Such is one of the advantages of the community here - ask one question but receive answers from different perspectives or based upon different interpretations!) There is a MicroPython which works well on Raspberry Pi SBCs, whereas there is a version of C which is native to the Arduino. Another 'trick', which may be open to you, is developing code on a larger (lap-top or desk-top) machine (with many more dev/debugging/testing facilities) and only transferring the code into the SBC once it is basically (or completely) working! A concern is that it can be confusing trying to learn two languages at once - and a fairly-similar, but significantly-different, pair at that. Recommend one at a time! So, depending upon which SBC you've already purchased/plan to buy first, go with the applicable language (and then pick-up the other when you move-on to the next project)... As Alan said, having learned one language it is relatively easy to learn another. However, try to resist the temptation to 'see' Python in terms of VB. Even where the commands are the same word, they may not perform in exactly the same way. On top of that, we talk about "idioms" which are quite different - implementing a noticeably different set of philosophies from VB specifically, and MSFT in general. I like Python because there is no intermediate step - one writes some code and it will runs. The benefits of immediacy can hardly be under-stated. The only issues in the environments you've mentioned, are things like running-out of storage space - but there are multiple ways to deal with such challenges... Yes, good to keep the grey-cells receptive, and we'll look forward to seeing more of what you get up-to (Silver-surfers of the world unite!) -- Regards =dn From __peter__ at web.de Sat Jun 6 05:25:19 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 06 Jun 2020 11:25:19 +0200 Subject: [Tutor] pandas.to_clipboard() copies nothing References: Message-ID: Jim wrote: > Mint18.3, python3.6, pandas 0.24.1 > > > et_file = '/home/jfb/Downloads/PortfolioDownload.csv' > df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, > engine='python') > df.to_clipboard(sep=',') > print(df) > > Manual notes the following. I'm not using PyQt4, but xclip is installed. > > Notes: Requirements for your platform. > > Linux : xclip, or xsel (with PyQt4 modules) > Windows : none > OS X : none > > The print command prints what I expect to see. > > I don't use pandas that much so maybe I am missing something. The pandas side seems OK; maybe you are looking at the wrong selection? I have a slightly different setup, and the following works for me: $ python3 Python 3.4.3 (default, Nov 12 2018, 22:25:49) [GCC 4.8.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas >>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"]) >>> df.to_clipboard(sep=", ") >>> $ xclip -o -selection clipboard Ham Spam 0 1 2 1 3 4$ From __peter__ at web.de Sat Jun 6 05:47:12 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 06 Jun 2020 11:47:12 +0200 Subject: [Tutor] pandas.to_clipboard() copies nothing References: Message-ID: Peter Otten wrote: > I have a slightly different setup, and the following works for me: > > $ python3 > Python 3.4.3 (default, Nov 12 2018, 22:25:49) > [GCC 4.8.4] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import pandas >>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"]) >>>> df.to_clipboard(sep=", ") >>>> > $ xclip -o -selection clipboard > Ham Spam > 0 1 2 > 1 3 4$ Except that the 2-char sep is ignored ;) From jf_byrnes at comcast.net Sat Jun 6 11:29:58 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 6 Jun 2020 10:29:58 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On 6/6/20 4:25 AM, Peter Otten wrote: > Jim wrote: > >> Mint18.3, python3.6, pandas 0.24.1 >> >> >> et_file = '/home/jfb/Downloads/PortfolioDownload.csv' >> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, >> engine='python') >> df.to_clipboard(sep=',') >> print(df) >> >> Manual notes the following. I'm not using PyQt4, but xclip is installed. >> >> Notes: Requirements for your platform. >> >> Linux : xclip, or xsel (with PyQt4 modules) >> Windows : none >> OS X : none >> >> The print command prints what I expect to see. >> >> I don't use pandas that much so maybe I am missing something. > > The pandas side seems OK; maybe you are looking at the wrong selection? > I have a slightly different setup, and the following works for me: > > $ python3 > Python 3.4.3 (default, Nov 12 2018, 22:25:49) > [GCC 4.8.4] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import pandas >>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"]) >>>> df.to_clipboard(sep=", ") >>>> > $ xclip -o -selection clipboard > Ham Spam > 0 1 2 > 1 3 4$ > Peter, I'm not sure what you mean by the "wrong selection" above. I ran your code and got the following results. This version (space after ,) worked despite the error msg: Python 3.6.10 (default, Dec 19 2019, 23:04:32) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"]) >>> df.to_clipboard(sep=", ") QApplication: invalid style override passed, ignoring it. Available styles: Windows, Fusion /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: UserWarning: to_clipboard in excel mode requires a single character separator. warnings.warn('to_clipboard in excel mode requires a single ' Copied from clipboard: Ham Spam 0 1 2 1 3 3 This version (no space after ,) also worked despite a different error msg: (env36) jfb at jims-mint18 ~ $ python Python 3.6.10 (default, Dec 19 2019, 23:04:32) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"]) >>> df.to_clipboard(sep=",") QApplication: invalid style override passed, ignoring it. Available styles: Windows, Fusion Copied from clipboard: ,Ham,Spam 0,1,2 1,3,4 I had a little test file I was using to figure out pandas so I dropped your code in it. Nothing was copied to the clipboard and this is the error msg: (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py QApplication: invalid style override passed, ignoring it. Available styles: Windows, Fusion /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: UserWarning: to_clipboard in excel mode requires a single character separator. warnings.warn('to_clipboard in excel mode requires a single ' So I added excel=False and dropped the sep= and got this error: (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py QApplication: invalid style override passed, ignoring it. Available styles: Windows, Fusion I don't understand the QApplication reference. I assume it refers to QT I have some QT stuff installed: from pip list: PyQt5 5.12 PyQt5-sip 4.19.14 qtconsole 4.4.3 I don't know why QT would come into play here and I don't understand the reference to excel when it was not included. To sum up. If I run it from the python console it give an error, but copies to the clipboard. If I run the python file from the terminal it gives an error and does not copy to the clipboard. Thanks, Jim From __peter__ at web.de Sat Jun 6 14:39:59 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 06 Jun 2020 20:39:59 +0200 Subject: [Tutor] pandas.to_clipboard() copies nothing References: Message-ID: Jim wrote: > On 6/6/20 4:25 AM, Peter Otten wrote: >> Jim wrote: >> >>> Mint18.3, python3.6, pandas 0.24.1 >>> >>> >>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv' >>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, >>> engine='python') >>> df.to_clipboard(sep=',') >>> print(df) >>> >>> Manual notes the following. I'm not using PyQt4, but xclip is installed. >>> >>> Notes: Requirements for your platform. >>> >>> Linux : xclip, or xsel (with PyQt4 modules) >>> Windows : none >>> OS X : none >>> >>> The print command prints what I expect to see. >>> >>> I don't use pandas that much so maybe I am missing something. >> >> The pandas side seems OK; maybe you are looking at the wrong selection? >> I have a slightly different setup, and the following works for me: >> >> $ python3 >> Python 3.4.3 (default, Nov 12 2018, 22:25:49) >> [GCC 4.8.4] on linux >> Type "help", "copyright", "credits" or "license" for more information. >>>>> import pandas >>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"]) >>>>> df.to_clipboard(sep=", ") >>>>> >> $ xclip -o -selection clipboard >> Ham Spam >> 0 1 2 >> 1 3 4$ >> > > Peter, > > I'm not sure what you mean by the "wrong selection" above. I ran your > code and got the following results. > > > This version (space after ,) worked despite the error msg: > > Python 3.6.10 (default, Dec 19 2019, 23:04:32) > [GCC 5.4.0 20160609] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import pandas > >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"]) > >>> df.to_clipboard(sep=", ") > QApplication: invalid style override passed, ignoring it. > Available styles: Windows, Fusion > /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: > UserWarning: to_clipboard in excel mode requires a single character > separator. > warnings.warn('to_clipboard in excel mode requires a single ' > > Copied from clipboard: > Ham Spam > 0 1 2 > 1 3 3 > > This version (no space after ,) also worked despite a different error msg: > > (env36) jfb at jims-mint18 ~ $ python > Python 3.6.10 (default, Dec 19 2019, 23:04:32) > [GCC 5.4.0 20160609] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import pandas > >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"]) > >>> df.to_clipboard(sep=",") > QApplication: invalid style override passed, ignoring it. > Available styles: Windows, Fusion > > Copied from clipboard: > ,Ham,Spam > 0,1,2 > 1,3,4 > > > I had a little test file I was using to figure out pandas so I dropped > your code in it. Nothing was copied to the clipboard and this is the > error msg: > > (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py > QApplication: invalid style override passed, ignoring it. > Available styles: Windows, Fusion > /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: > UserWarning: to_clipboard in excel mode requires a single character > separator. > warnings.warn('to_clipboard in excel mode requires a single ' > > So I added excel=False and dropped the sep= and got this error: > > (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py > QApplication: invalid style override passed, ignoring it. > Available styles: Windows, Fusion > > I don't understand the QApplication reference. I assume it refers to QT > I have some QT stuff installed: > > from pip list: > PyQt5 5.12 > PyQt5-sip 4.19.14 > qtconsole 4.4.3 > > I don't know why QT would come into play here and I don't understand the > reference to excel when it was not included. > > To sum up. If I run it from the python console it give an error, but > copies to the clipboard. If I run the python file from the terminal it > gives an error and does not copy to the clipboard. Most of your errors seem to be warnings. Looking into the code writing to the clipboard shows that it requires the DISPLAY environment variable to be set, so I'd check that in the terminal. https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539 shows that if HAS_DISPLAY: if _executable_exists("xsel"): return init_xsel_clipboard() if _executable_exists("xclip"): return init_xclip_clipboard() if _executable_exists("klipper") and _executable_exists("qdbus"): return init_klipper_clipboard() ... [try qt] QT is the last option. From that we can conclude that xclip is not found. Maybe you can fix that by adjusting the path. Or you try to set the clipboard mechanism explicitly with pandas.io.clipboard.set_clipboard("xclip") From robertvstepp at gmail.com Sat Jun 6 15:13:10 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 14:13:10 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On Sat, Jun 6, 2020 at 1:40 PM Peter Otten <__peter__ at web.de> wrote: > > Jim wrote: > > > On 6/6/20 4:25 AM, Peter Otten wrote: > >> Jim wrote: > >> > >>> Mint18.3, python3.6, pandas 0.24.1 > >>> > >>> > >>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv' > >>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, > >>> engine='python') > >>> df.to_clipboard(sep=',') > >>> print(df) > >>> > >>> Manual notes the following. I'm not using PyQt4, but xclip is installed. > >>> > >>> Notes: Requirements for your platform. > >>> > >>> Linux : xclip, or xsel (with PyQt4 modules) > >>> Windows : none > >>> OS X : none > > To sum up. If I run it from the python console it give an error, but > > copies to the clipboard. If I run the python file from the terminal it > > gives an error and does not copy to the clipboard. > > Most of your errors seem to be warnings. > > Looking into the code writing to the clipboard shows that it requires the > DISPLAY environment variable to be set, so I'd check that in the terminal. > > https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539 > > shows that > > if HAS_DISPLAY: > if _executable_exists("xsel"): > return init_xsel_clipboard() > if _executable_exists("xclip"): > return init_xclip_clipboard() > if _executable_exists("klipper") and _executable_exists("qdbus"): > return init_klipper_clipboard() > ... [try qt] > > QT is the last option. From that we can conclude that xclip is not found. > Maybe you can fix that by adjusting the path. > Or you try to set the clipboard mechanism explicitly with > > pandas.io.clipboard.set_clipboard("xclip") I don't know if this is relevant or not, but when I installed Neovim on my PC I found that I could not access the system clipboard from within Neovim. Investigation discovered that xsel was not installed. Like Jim I am using Linux Mint. Once I installed xsel those problems went away. I cannot recall if I had to do any special configurations for xsel or not. -- boB From jf_byrnes at comcast.net Sat Jun 6 17:26:57 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 6 Jun 2020 16:26:57 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On 6/6/20 2:13 PM, boB Stepp wrote: > On Sat, Jun 6, 2020 at 1:40 PM Peter Otten <__peter__ at web.de> wrote: >> >> Jim wrote: >> >>> On 6/6/20 4:25 AM, Peter Otten wrote: >>>> Jim wrote: >>>> >>>>> Mint18.3, python3.6, pandas 0.24.1 >>>>> >>>>> >>>>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv' >>>>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, >>>>> engine='python') >>>>> df.to_clipboard(sep=',') >>>>> print(df) >>>>> >>>>> Manual notes the following. I'm not using PyQt4, but xclip is installed. >>>>> >>>>> Notes: Requirements for your platform. >>>>> >>>>> Linux : xclip, or xsel (with PyQt4 modules) >>>>> Windows : none >>>>> OS X : none > >>> To sum up. If I run it from the python console it give an error, but >>> copies to the clipboard. If I run the python file from the terminal it >>> gives an error and does not copy to the clipboard. >> >> Most of your errors seem to be warnings. >> >> Looking into the code writing to the clipboard shows that it requires the >> DISPLAY environment variable to be set, so I'd check that in the terminal. >> >> https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539 >> >> shows that >> >> if HAS_DISPLAY: >> if _executable_exists("xsel"): >> return init_xsel_clipboard() >> if _executable_exists("xclip"): >> return init_xclip_clipboard() >> if _executable_exists("klipper") and _executable_exists("qdbus"): >> return init_klipper_clipboard() >> ... [try qt] >> >> QT is the last option. From that we can conclude that xclip is not found. >> Maybe you can fix that by adjusting the path. >> Or you try to set the clipboard mechanism explicitly with >> >> pandas.io.clipboard.set_clipboard("xclip") > > I don't know if this is relevant or not, but when I installed Neovim > on my PC I found that I could not access the system clipboard from > within Neovim. Investigation discovered that xsel was not installed. > Like Jim I am using Linux Mint. Once I installed xsel those problems > went away. I cannot recall if I had to do any special configurations > for xsel or not. Bob, See my last reply to Peter (it hasn't shown up yet as I write this). xclip and xsel are installed. I got it to work by deleting the QT stuff from my virtual environment. Regards, Jim From robertvstepp at gmail.com Sat Jun 6 21:47:43 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 20:47:43 -0500 Subject: [Tutor] Still not understanding passing filenames in Python Message-ID: <20200607014743.GA10604@Dream-Machine1> Now in "3.4 Modules" at https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html Earlier in the course I wrote a program, report.py, that runs as so: bob at Dream-Machine1:~/practical-python/Work$ python3 report.py Enter path to portfolio file: Data/portfolio.csv Enter path to stock prices file: Data/prices.csv Name Shares Price Change ---------- ---------- ---------- ---------- AA 100 $9.22 -22.98 IBM 50 $106.28 15.18 CAT 150 $35.46 -47.98 MSFT 200 $20.89 -30.34 GE 95 $13.48 -26.89 MSFT 50 $20.89 -44.21 IBM 100 $106.28 35.84 Current portfolio value = $28,686.10 Current portfolio gain/loss = $-15,985.05 In "Exercise 3.12: Using your library module" Beazley has us importing the recently discussed fileparse module containing the parse_csv() function to replace the code previously written in the read_portfolio() function in report.py. So I added "import fileparse" and modified the read_portfolio() function to: def read_portfolio(filename: str) -> List[Dict[str, Union[str, int, float]]]: """Read a file and return a portfolio list of records.""" portfolio = fileparse.parse_csv( filename, select=["name", "shares", "price"], types=[str, int, float] ) return portfolio report.py and fileparse.py are both in the same Work directory. Data is a subdirectory of Work. But when I try to run this program with the same file location entries I get: bob at Dream-Machine1:~/practical-python/Work$ python3 report.py Enter path to portfolio file: Data/porfolio.csv Enter path to stock prices file: Data/prices.csv Traceback (most recent call last): File "report.py", line 113, in main() File "report.py", line 104, in main portfolio = read_portfolio(portfolio_path) File "report.py", line 18, in read_portfolio filename, select=["name", "shares", "price"], types=[str, int, float] File "/home/bob/practical-python/Work/fileparse.py", line 25, in parse_csv with open(filename) as fileobj: FileNotFoundError: [Errno 2] No such file or directory: 'Data/porfolio.csv' If I use absolute file paths, "/home/bob/practical-python..." it works. If I use "./Data/portfolio.csv" and "./Data/prices.csv" it works. I currently do not understand the differences. Obviously I do understand one or more things. A helpful explanation please? Thanks! -- Wishing you only the best, boB Stepp From PyTutor at danceswithmice.info Sat Jun 6 22:19:09 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 7 Jun 2020 14:19:09 +1200 Subject: [Tutor] Still not understanding passing filenames in Python In-Reply-To: <20200607014743.GA10604@Dream-Machine1> References: <20200607014743.GA10604@Dream-Machine1> Message-ID: <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info> On 7/06/20 1:47 PM, boB Stepp wrote: > Now in "3.4 Modules" at > https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html > > > Earlier in the course I wrote a program, report.py, that runs as so: > > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > Enter path to portfolio file:? Data/portfolio.csv > Enter path to stock prices file:? Data/prices.csv > > ????? Name???? Shares????? Price???? Change ---------- ---------- > ---------- ---------- ??????? AA??????? 100????? $9.22???? -22.98 > ?????? IBM???????? 50??? $106.28????? 15.18 > ?????? CAT??????? 150???? $35.46???? -47.98 > ????? MSFT??????? 200???? $20.89???? -30.34 > ??????? GE???????? 95???? $13.48???? -26.89 > ????? MSFT???????? 50???? $20.89???? -44.21 > ?????? IBM??????? 100??? $106.28????? 35.84 > > Current portfolio value = $28,686.10 > Current portfolio gain/loss = $-15,985.05 > > In "Exercise 3.12: Using your library module" Beazley has us importing the > recently discussed fileparse module containing the parse_csv() function to > replace the code previously written in the read_portfolio() function in > report.py.? So I added "import fileparse" and modified the read_portfolio() > function to: > > def read_portfolio(filename: str) -> List[Dict[str, Union[str, int, > float]]]: > ??? """Read a file and return a portfolio list of records.""" > ??? portfolio = fileparse.parse_csv( > ??????? filename, select=["name", "shares", "price"], types=[str, int, > float] > ??? ) > ??? return portfolio > > report.py and fileparse.py are both in the same Work directory.? Data is a > subdirectory of Work. > > But when I try to run this program with the same file location entries > I get: > > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > Enter path to portfolio file:? Data/porfolio.csv > Enter path to stock prices file:? Data/prices.csv > Traceback (most recent call last): > ? File "report.py", line 113, in > ??? main() > ? File "report.py", line 104, in main > ??? portfolio = read_portfolio(portfolio_path) > ? File "report.py", line 18, in read_portfolio > ??? filename, select=["name", "shares", "price"], types=[str, int, float] > ? File "/home/bob/practical-python/Work/fileparse.py", line 25, in > parse_csv > ??? with open(filename) as fileobj: > FileNotFoundError: [Errno 2] No such file or directory: 'Data/porfolio.csv' > > If I use absolute file paths, "/home/bob/practical-python..." it works. > > If I use "./Data/portfolio.csv" and "./Data/prices.csv" it works.? I > currently do not understand the differences.? Obviously I do understand one > or more things.? A helpful explanation please?? Thanks! Please don't shoot the piano player (or the Latin teacher)... is the fileNM correct? > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > Enter path to portfolio file: Data/portfolio.csv ... > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > Enter path to portfolio file: Data/porfolio.csv -- Regards =dn From robertvstepp at gmail.com Sat Jun 6 22:19:47 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 21:19:47 -0500 Subject: [Tutor] Unnecessary comprehension warning Message-ID: <20200607021947.GB10604@Dream-Machine1> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. I rewrote another function in report.py, read_prices(), to make use of the parse_csv() function in the fileparse module. The rewritten function is: def read_prices(filename: str) -> Dict[str, float]: """Read a file of stock prices and load them into a dictionary.""" prices = fileparse.parse_csv(filename, types=[str, float], has_headers=False) stock_prices = {stock_name: stock_price for stock_name, stock_price in prices} return stock_prices pylint complains with: report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use of a comprehension The dictionary comprehension I'm now using replaces a lengthier for loop with indexing instead of nice names. Am I truly doing things in a bad Python style as the linter is complaining? Should I be doing this differently? -- Wishing you only the best, boB Stepp From PyTutor at danceswithmice.info Sat Jun 6 22:29:24 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 7 Jun 2020 14:29:24 +1200 Subject: [Tutor] Unnecessary comprehension warning In-Reply-To: <20200607021947.GB10604@Dream-Machine1> References: <20200607021947.GB10604@Dream-Machine1> Message-ID: <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> On 7/06/20 2:19 PM, boB Stepp wrote: > Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at > https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. > > > I rewrote another function in report.py, read_prices(), to make use of the > parse_csv() function in the fileparse module.? The rewritten function is: > > def read_prices(filename: str) -> Dict[str, float]: > ??? """Read a file of stock prices and load them into a dictionary.""" > ??? prices = fileparse.parse_csv(filename, types=[str, float], > has_headers=False) > ??? stock_prices = {stock_name: stock_price for stock_name, stock_price > in prices} > ??? return stock_prices > > pylint complains with: > > report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use > of a comprehension > > The dictionary comprehension I'm now using replaces a lengthier for loop > with indexing instead of nice names.? Am I truly doing things in a bad > Python style as the linter is complaining?? Should I be doing this > differently? The name "prices" is defined and then used, but enjoys no further reference. What happens (from PyLint's PoV) if you make the two lines into one? (overly-complicated and ugly though it would be) -- Regards =dn From PyTutor at danceswithmice.info Sat Jun 6 22:45:24 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 7 Jun 2020 14:45:24 +1200 Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type annotation errors) In-Reply-To: <20200606014015.GQ23247@Dream-Machine1> References: <20200606014015.GQ23247@Dream-Machine1> Message-ID: <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info> On 6/06/20 1:40 PM, boB Stepp wrote: > DL Neil wrote: >> boB wrote: >>> Peter wrote: >>> In terms of following along with Beazley's course material this would be >>> cheating.? Classes have not been presented yet.? Even very simple ones. >>> ~(:>)) >>> >>>> PPS: For someone who knows a little C the obvious fix for your >>>> version is to >>>> cast the union to the expected type: > >> This is a little difficult to rationalise: >> - we are not trying to get ahead of the course material >> - but we are prepared to launch into complex (if not complicated) mypy >> Apologies, I can see the 'why' but can't help but feel it is only that >> imbalance which has led to the problem... > > HALT!? *I* am solely responsible for mixing in type annotations, not Mr. > Beazley.? As you know I have been working on learning these.? While I am > working through his course I am practicing type annotations.? Beazley does > briefly mention type annotations, but so far he has not asked the reader of > his course to do anything with them.? Any resulting messy annotations are > the sole responsibility of daboB (*not* dabeaz). Understood, and that's the point: having accepted the assignment's status as 'incomplete' (and without typing), it has then had advanced typing techniques applied. There lies the imbalance. Further, adding class technology to the assignment was described as "cheating" - because it is a future topic (one expects). Yet advanced typing, also not/yet to be covered in the course, is not "cheating"? Given that 'the other David' has been a trainer almost as long as I (but he as a Python trainer - which I am (formally) not!), it seemed reasonable teaching technique/planning that the course would build further (per more-recent messages to this list). Perhaps the assertion of it being a useful utility back-then, was somewhat premature, and better applied to its 'final' iteration of development? -- Regards =dn From robertvstepp at gmail.com Sat Jun 6 22:50:34 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 21:50:34 -0500 Subject: [Tutor] Still not understanding passing filenames in Python In-Reply-To: <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info> References: <20200607014743.GA10604@Dream-Machine1> <310e678c-7911-ff86-4d1f-f93237cf582b@DancesWithMice.info> Message-ID: On Sat, Jun 6, 2020 at 9:19 PM DL Neil via Tutor wrote: > > On 7/06/20 1:47 PM, boB Stepp wrote: > Please don't shoot the piano player (or the Latin teacher)... > is the fileNM correct? > > > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > > > Enter path to portfolio file: Data/portfolio.csv > > ... > > > bob at Dream-Machine1:~/practical-python/Work$ python3 report.py > > > > Enter path to portfolio file: Data/porfolio.csv You don't know how many times I read and reread these lines! Don't worry, your safety is ensured. New computer glasses may be in order though. Thanks! -- boB From robertvstepp at gmail.com Sat Jun 6 23:00:09 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 22:00:09 -0500 Subject: [Tutor] Unnecessary comprehension warning In-Reply-To: <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> References: <20200607021947.GB10604@Dream-Machine1> <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> Message-ID: On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor wrote: > > On 7/06/20 2:19 PM, boB Stepp wrote: > > Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at > > https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. > > > > > > I rewrote another function in report.py, read_prices(), to make use of the > > parse_csv() function in the fileparse module. The rewritten function is: > > > > def read_prices(filename: str) -> Dict[str, float]: > > """Read a file of stock prices and load them into a dictionary.""" > > prices = fileparse.parse_csv(filename, types=[str, float], > > has_headers=False) > > stock_prices = {stock_name: stock_price for stock_name, stock_price > > in prices} > > return stock_prices > > > > pylint complains with: > > > > report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use > > of a comprehension > > > > The dictionary comprehension I'm now using replaces a lengthier for loop > > with indexing instead of nice names. Am I truly doing things in a bad > > Python style as the linter is complaining? Should I be doing this > > differently? > > > The name "prices" is defined and then used, but enjoys no further reference. > > What happens (from PyLint's PoV) if you make the two lines into one? > (overly-complicated and ugly though it would be) Strangely, it makes no difference, same warning. -- boB From PyTutor at danceswithmice.info Sat Jun 6 23:13:42 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Sun, 7 Jun 2020 15:13:42 +1200 Subject: [Tutor] Unnecessary comprehension warning In-Reply-To: References: <20200607021947.GB10604@Dream-Machine1> <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> Message-ID: <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info> On 7/06/20 3:00 PM, boB Stepp wrote: > On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor wrote: >> >> On 7/06/20 2:19 PM, boB Stepp wrote: >>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at >>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. >>> >>> >>> I rewrote another function in report.py, read_prices(), to make use of the >>> parse_csv() function in the fileparse module. The rewritten function is: >>> >>> def read_prices(filename: str) -> Dict[str, float]: >>> """Read a file of stock prices and load them into a dictionary.""" >>> prices = fileparse.parse_csv(filename, types=[str, float], >>> has_headers=False) >>> stock_prices = {stock_name: stock_price for stock_name, stock_price >>> in prices} >>> return stock_prices >>> >>> pylint complains with: >>> >>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use >>> of a comprehension >>> >>> The dictionary comprehension I'm now using replaces a lengthier for loop >>> with indexing instead of nice names. Am I truly doing things in a bad >>> Python style as the linter is complaining? Should I be doing this >>> differently? >> >> >> The name "prices" is defined and then used, but enjoys no further reference. >> >> What happens (from PyLint's PoV) if you make the two lines into one? >> (overly-complicated and ugly though it would be) > > Strangely, it makes no difference, same warning. After fileparse, what is type( prices )? -- Regards =dn From robertvstepp at gmail.com Sun Jun 7 00:15:03 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 6 Jun 2020 23:15:03 -0500 Subject: [Tutor] Unnecessary comprehension warning In-Reply-To: <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info> References: <20200607021947.GB10604@Dream-Machine1> <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info> Message-ID: On Sat, Jun 6, 2020 at 10:14 PM DL Neil via Tutor wrote: > > On 7/06/20 3:00 PM, boB Stepp wrote: > > On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor wrote: > >> > >> On 7/06/20 2:19 PM, boB Stepp wrote: > >>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at > >>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. > >>> > >>> > >>> I rewrote another function in report.py, read_prices(), to make use of the > >>> parse_csv() function in the fileparse module. The rewritten function is: > >>> > >>> def read_prices(filename: str) -> Dict[str, float]: > >>> """Read a file of stock prices and load them into a dictionary.""" > >>> prices = fileparse.parse_csv(filename, types=[str, float], > >>> has_headers=False) > >>> stock_prices = {stock_name: stock_price for stock_name, stock_price > >>> in prices} > >>> return stock_prices > >>> > >>> pylint complains with: > >>> > >>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use > >>> of a comprehension > >>> > >>> The dictionary comprehension I'm now using replaces a lengthier for loop > >>> with indexing instead of nice names. Am I truly doing things in a bad > >>> Python style as the linter is complaining? Should I be doing this > >>> differently? > >> > >> > >> The name "prices" is defined and then used, but enjoys no further reference. > >> > >> What happens (from PyLint's PoV) if you make the two lines into one? > >> (overly-complicated and ugly though it would be) > > > > Strangely, it makes no difference, same warning. > > > After fileparse, what is type( prices )? type(prices) = -- boB From robertvstepp at gmail.com Sun Jun 7 01:24:35 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 7 Jun 2020 00:24:35 -0500 Subject: [Tutor] Unnecessary comprehension warning In-Reply-To: References: <20200607021947.GB10604@Dream-Machine1> <077b22ca-cf5b-f2fa-c7d2-c74bf648df6c@DancesWithMice.info> <06c9ad95-9f36-9893-ea33-de83fd8bd54a@DancesWithMice.info> Message-ID: On Sat, Jun 6, 2020 at 11:15 PM boB Stepp wrote: > > On Sat, Jun 6, 2020 at 10:14 PM DL Neil via Tutor wrote: > > > > On 7/06/20 3:00 PM, boB Stepp wrote: > > > On Sat, Jun 6, 2020 at 9:29 PM DL Neil via Tutor wrote: > > >> > > >> On 7/06/20 2:19 PM, boB Stepp wrote: > > >>> Continuing "Exercise 3.12: Using your library module" in "3.4 Modules" at > > >>> https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/04_Modules.html. > > >>> > > >>> > > >>> I rewrote another function in report.py, read_prices(), to make use of the > > >>> parse_csv() function in the fileparse module. The rewritten function is: > > >>> > > >>> def read_prices(filename: str) -> Dict[str, float]: > > >>> """Read a file of stock prices and load them into a dictionary.""" > > >>> prices = fileparse.parse_csv(filename, types=[str, float], > > >>> has_headers=False) > > >>> stock_prices = {stock_name: stock_price for stock_name, stock_price > > >>> in prices} > > >>> return stock_prices > > >>> > > >>> pylint complains with: > > >>> > > >>> report.py|25 col 1 warning| unnecessary-comprehension: Unnecessary use > > >>> of a comprehension > > >>> > > >>> The dictionary comprehension I'm now using replaces a lengthier for loop > > >>> with indexing instead of nice names. Am I truly doing things in a bad > > >>> Python style as the linter is complaining? Should I be doing this > > >>> differently? Finally figured it out. The linter was correct! I should just return the following: return dict(fileparse.parse_csv(fileobj, types=[str, float], has_headers=False)) Doh! -- boB From jf_byrnes at comcast.net Sat Jun 6 23:44:05 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 6 Jun 2020 22:44:05 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On 6/6/20 1:39 PM, Peter Otten wrote: Peter, I see that my original message never showed up so I am re-sending it. > Jim wrote: > >> On 6/6/20 4:25 AM, Peter Otten wrote: >>> Jim wrote: >>> >>>> Mint18.3, python3.6, pandas 0.24.1 >>>> >>>> >>>> et_file = '/home/jfb/Downloads/PortfolioDownload.csv' >>>> df = pd.read_csv(et_file, header=6, usecols=[0, 7], skipfooter=6, >>>> engine='python') >>>> df.to_clipboard(sep=',') >>>> print(df) >>>> >>>> Manual notes the following. I'm not using PyQt4, but xclip is installed. >>>> >>>> Notes: Requirements for your platform. >>>> >>>> Linux : xclip, or xsel (with PyQt4 modules) >>>> Windows : none >>>> OS X : none >>>> >>>> The print command prints what I expect to see. >>>> >>>> I don't use pandas that much so maybe I am missing something. >>> >>> The pandas side seems OK; maybe you are looking at the wrong selection? >>> I have a slightly different setup, and the following works for me: >>> >>> $ python3 >>> Python 3.4.3 (default, Nov 12 2018, 22:25:49) >>> [GCC 4.8.4] on linux >>> Type "help", "copyright", "credits" or "license" for more information. >>>>>> import pandas >>>>>> df = pandas.DataFrame([[1,2], [3, 4]], columns=["Ham", "Spam"]) >>>>>> df.to_clipboard(sep=", ") >>>>>> >>> $ xclip -o -selection clipboard >>> Ham Spam >>> 0 1 2 >>> 1 3 4$ >>> >> >> Peter, >> >> I'm not sure what you mean by the "wrong selection" above. I ran your >> code and got the following results. >> >> >> This version (space after ,) worked despite the error msg: >> >> Python 3.6.10 (default, Dec 19 2019, 23:04:32) >> [GCC 5.4.0 20160609] on linux >> Type "help", "copyright", "credits" or "license" for more information. >> >>> import pandas >> >>> df = pandas.DataFrame([[1,2,], [3,3]], columns=["Ham", "Spam"]) >> >>> df.to_clipboard(sep=", ") >> QApplication: invalid style override passed, ignoring it. >> Available styles: Windows, Fusion >> /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: >> UserWarning: to_clipboard in excel mode requires a single character >> separator. >> warnings.warn('to_clipboard in excel mode requires a single ' >> >> Copied from clipboard: >> Ham Spam >> 0 1 2 >> 1 3 3 >> >> This version (no space after ,) also worked despite a different error msg: >> >> (env36) jfb at jims-mint18 ~ $ python >> Python 3.6.10 (default, Dec 19 2019, 23:04:32) >> [GCC 5.4.0 20160609] on linux >> Type "help", "copyright", "credits" or "license" for more information. >> >>> import pandas >> >>> df = pandas.DataFrame([[1,2], [3,4]], columns=["Ham", "Spam"]) >> >>> df.to_clipboard(sep=",") >> QApplication: invalid style override passed, ignoring it. >> Available styles: Windows, Fusion >> >> Copied from clipboard: >> ,Ham,Spam >> 0,1,2 >> 1,3,4 >> >> >> I had a little test file I was using to figure out pandas so I dropped >> your code in it. Nothing was copied to the clipboard and this is the >> error msg: >> >> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py >> QApplication: invalid style override passed, ignoring it. >> Available styles: Windows, Fusion >> /home/jfb/EVs/env36/lib/python3.6/site-packages/pandas/io/clipboards.py:134: >> UserWarning: to_clipboard in excel mode requires a single character >> separator. >> warnings.warn('to_clipboard in excel mode requires a single ' >> >> So I added excel=False and dropped the sep= and got this error: >> >> (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py >> QApplication: invalid style override passed, ignoring it. >> Available styles: Windows, Fusion >> >> I don't understand the QApplication reference. I assume it refers to QT >> I have some QT stuff installed: >> >> from pip list: >> PyQt5 5.12 >> PyQt5-sip 4.19.14 >> qtconsole 4.4.3 >> >> I don't know why QT would come into play here and I don't understand the >> reference to excel when it was not included. >> >> To sum up. If I run it from the python console it give an error, but >> copies to the clipboard. If I run the python file from the terminal it >> gives an error and does not copy to the clipboard. > > Most of your errors seem to be warnings. > > Looking into the code writing to the clipboard shows that it requires the > DISPLAY environment variable to be set, so I'd check that in the terminal. > > https://github.com/pandas-dev/pandas/blob/master/pandas/io/clipboard/__init__.py#L539 > > shows that > > if HAS_DISPLAY: > if _executable_exists("xsel"): > return init_xsel_clipboard() > if _executable_exists("xclip"): > return init_xclip_clipboard() > if _executable_exists("klipper") and _executable_exists("qdbus"): > return init_klipper_clipboard() > ... [try qt] > > QT is the last option. From that we can conclude that xclip is not found. > Maybe you can fix that by adjusting the path. > Or you try to set the clipboard mechanism explicitly with > > pandas.io.clipboard.set_clipboard("xclip") > Well I have it working. I have a VE with python 3.5 in it, no QT installed. I ran the test script and it copied the info to the clipboard. I went back to the VE with 3.6 and upgraded PyQt5 & PyQt5-sip. I ran the test script and it gave a Qt error basically saying it could not load a plugin even though it was installed. At that point I uninstalled the Qt stuff from the 3.6 VE and the script copied the dataframe to the clipboard. Then I tried your xclip command. xclip -o -selection clipboard ,Ham,Spam 0,1,2 1,3,4 Here is the output of items containing QT or DISPLAY from printenv: QT_STYLE_OVERRIDE= QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1 QT_ACCESSIBILITY=1 QT_QPA_PLATFORMTHEME=qgnomeplatform QT4_IM_MODULE=xim DISPLAY=:0 You certainly know more about this than I do, but I wonder about the conclusion that xclip is not found. In VE 3.5 and now VE 3.6 there is no QT to fall back on but the script worked and xclip worked after the script ran. I don't know what DISPLAY should equal. I don't think I need QT any more so I am going to stop trying to figure this out and try to finish the script I was working on. I do plan on coming back and see if there is a different solution other than deleting PyQt5. I do want to thank you for all the help you have given me in this matter. Regards, Jim From manpritsinghece at gmail.com Sun Jun 7 01:48:41 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sun, 7 Jun 2020 11:18:41 +0530 Subject: [Tutor] Fwd: Question regarding use of assignment expression in python 3.8.3 In-Reply-To: References: Message-ID: Dear All, According to Heron's formula for finding area of a triangle , if the sides of a triangle are a, b & c is : area =sqrt( s * (s-a) * (s-b) * (s-c)) # sqrt means square root where s = (a+b+c) / 2 so for finding the area of the triangle using Heron's formula in Python , if i write code like this , will it be a valid practise ? I have used assignment expression while calculating the area a = int(input("Enter value of first side")) # Assuming value is integer b = int(input("Enter value of second side")) # Assuming value is integer c = int(input("Enter value of third side")) # Assuming value is integer area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5 print("Area of the triangle is", area) Regards Manprit Singh ---------- Forwarded message --------- From: Manprit Singh Date: Sat, Jun 6, 2020 at 11:59 PM Subject: Question regarding use of assignment expression in python 3.8.3 To: Dear all, According to Heron's formula for finding area of a triangle , if the sides of a triangle are a, b & c is : area =sqrt( s * (s-a) * (s-b) * (s-c)) # sqrt means square root where s = (a+b+c) / 2 so for finding the area of the triangle using Heron's formula in Python , if i write code like this , will it be a valid practise ? I have used assignment expression while calculating the area a = int(input("Enter value of first side")) # Assuming value is integer b = int(input("Enter value of second side")) # Assuming value is integer c = int(input("Enter value of third side")) # Assuming value is integer area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5 print("Area of the triangle is", area) Regards Manprit Singh From __peter__ at web.de Sun Jun 7 05:07:34 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 07 Jun 2020 11:07:34 +0200 Subject: [Tutor] pandas.to_clipboard() copies nothing References: Message-ID: Jim wrote: > You certainly know more about this than I do, but I wonder about the > conclusion that xclip is not found. I don't know much, "qt tried as last resort" is my interpretation of the latest pandas code, without actually running it. > I don't think I need QT any more so I am going to stop trying to figure > this out and try to finish the script I was working on. I do plan on > coming back and see if there is a different solution other than deleting > PyQt5. Did you try invoking pandas.io.clipboard.set_clipboard("xclip") before pasting? > I do want to thank you for all the help you have given me in this matter. You're welcome. From alan.gauld at yahoo.co.uk Sun Jun 7 07:10:32 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 7 Jun 2020 12:10:32 +0100 Subject: [Tutor] Fwd: Question regarding use of assignment expression in python 3.8.3 In-Reply-To: References: Message-ID: On 07/06/2020 06:48, Manprit Singh wrote: This appears to be a duplicate posting from a few days ago, so I'll send you the duplicate answer! :-) > so for finding the area of the triangle using Heron's formula in Python , > if i write code like this , will it be a valid practise ? Yes, if you just want to practice use of assignment expressions. > area = ((s := (a+b+c) /2) *(s -a)*(s-b)*(s-c))**0.5 Its syntactically valid to use it here but offers very no advantage over a separate assignment line s = a+b+c And has 2 minor disadvantages: 1) its more typing (2 keystrokes) 2) its harder to debug - no way to inspect s prior to executing the calculation. -- -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From bouncingcats at gmail.com Sun Jun 7 08:51:07 2020 From: bouncingcats at gmail.com (David) Date: Sun, 7 Jun 2020 22:51:07 +1000 Subject: [Tutor] Beginner Noob In-Reply-To: References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor wrote: > There is a MicroPython which works well on Raspberry Pi SBCs, whereas > there is a version of C which is native to the Arduino. May I offer a small correction, because this seems a bit misleading about the MicroPython project [1]. The whole point of MicroPython is that it has been designed to run directly on a tiny microcontroller, with no operating system required, and is optimised for doing so at the cost of other performance aspects. It can also run on Linux, for development. Raspberry Pi runs Linux. So although you *can* run MicroPython on a Raspberry Pi, you generally wouldn't, because there's no point, and any of the other Linux varieties of Python will probably perform better, generally speaking, because they will exploit all the advantages provided by the operating system. [1] https://micropython.org/ From alexkleider at protonmail.com Sun Jun 7 12:58:36 2020 From: alexkleider at protonmail.com (alexkleider) Date: Sun, 07 Jun 2020 16:58:36 +0000 Subject: [Tutor] Beginner Noob In-Reply-To: References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com> ??????? Original Message ??????? On Sunday, June 7, 2020 5:51 AM, David wrote: > On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor tutor at python.org wrote: > > > There is a MicroPython which works well on Raspberry Pi SBCs, whereas > > there is a version of C which is native to the Arduino. > > May I offer a small correction, because this seems a bit misleading about > the MicroPython project [1]. The whole point of MicroPython is that it > has been designed to run directly on a tiny microcontroller, with no > operating system required, and is optimised for doing so at the cost > of other performance aspects. It can also run on Linux, for development. > > Raspberry Pi runs Linux. So although you can run MicroPython on a > Raspberry Pi, you generally wouldn't, because there's no point, and > any of the other Linux varieties of Python will probably perform better, > generally speaking, because they will exploit all the advantages provided > by the operating system. > > [1] https://micropython.org/ A few comments that might be pertinent (from another grey head _without_ a tech background.) There was a tutorial given at the San Francisco Python MeetUp group at what may have been the last meeting they had before the lock-down. It was about microPython on the arduino. You might wish to look that up- there may be info related to it on line. I can try to look up contacts who might be helpful if you wish. I've used the RPi a lot- it is very Python orientated and I doubt that you'd run into difficulties because of limited resources, especially if you got a late model one- each model has more ports, more memory, faster processor, ... It's easy to run the Pi 'headless' so no need for setting up monitor, keyboard, mouse etc (as long as you are comfortable with SSH and the terminal command line.) Be happy to discuss further (on or off list, the latter perhaps being more appropriate since it will be mostly about the Pi rather than Python.) Cheers, Alex From robertvstepp at gmail.com Sun Jun 7 13:51:33 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 7 Jun 2020 12:51:33 -0500 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? Message-ID: <20200607175133.GC10604@Dream-Machine1> Now in "4.1 Classes" at https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html. Basic question for Python 3 only development: Is it better style to use "class ClassName:" or "class ClassName(object):"? Beazley uses the former in this material (so far). Other readings online (no citations handy) prefer being explicit with the latter. I note that pylint prefers omitting "(object)", calling it "useless-object-inheritance". I realize that if I am trying to write code compatible with both Python 2 and 3 that I need to explicitly inherit from "object". So, for Python 3 only development is there any consensus? Are there any real arguments for being "explicit" with inheriting from "object"? I have to say that I have not yet found the allusion to Zen to be explicit not convincing. -- Wishing you only the best, boB Stepp From mats at wichmann.us Sun Jun 7 14:15:03 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 7 Jun 2020 12:15:03 -0600 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: <20200607175133.GC10604@Dream-Machine1> References: <20200607175133.GC10604@Dream-Machine1> Message-ID: On 6/7/20 11:51 AM, boB Stepp wrote: > Now in "4.1 Classes" at > https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html. > > > Basic question for Python 3 only development:? Is it better style to use > "class ClassName:" or "class ClassName(object):"?? Beazley uses the former > in this material (so far).? Other readings online (no citations handy) > prefer being explicit with the latter.? I note that pylint prefers omitting > "(object)", calling it "useless-object-inheritance". > > I realize that if I am trying to write code compatible with both Python 2 > and 3 that I need to explicitly inherit from "object". > > So, for Python 3 only development is there any consensus?? Are there any > real arguments for being "explicit" with inheriting from "object"?? I have > to say that I have not yet found the allusion to Zen to be explicit not > convincing. Consensus? Hah! It seems kind of odd to need to supply something that is a guaranteed language feature: >>> class Spam: ... pass ... >>> Spam.__mro__ (, ) >>> But then, there can't be any confusion if you're explicit, and if you're writing code which might be considered for use in Python 2, then it's easier to keep it. I don't use (object), and recently submitted patches to a 20-year old project that has recently become Python3-only to drop them, which the maintainer accepted. Here's my claim: listen to pylint, or someday you'll end up having to defend why you're doing something pylint complains about. :) Tools like Pylint and Black are pretty opinionated (although Black is so opinionated that you can't override most of its choices, while Pylint is almost infintely configurable), and sometimes it's just easier to go with the flow. From Richard at Damon-Family.org Sun Jun 7 15:35:39 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Sun, 7 Jun 2020 15:35:39 -0400 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: <20200607175133.GC10604@Dream-Machine1> References: <20200607175133.GC10604@Dream-Machine1> Message-ID: On 6/7/20 1:51 PM, boB Stepp wrote: > Now in "4.1 Classes" at > https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html. > > > Basic question for Python 3 only development:? Is it better style to use > "class ClassName:" or "class ClassName(object):"?? Beazley uses the > former > in this material (so far).? Other readings online (no citations handy) > prefer being explicit with the latter.? I note that pylint prefers > omitting > "(object)", calling it "useless-object-inheritance". > > I realize that if I am trying to write code compatible with both Python 2 > and 3 that I need to explicitly inherit from "object". > > So, for Python 3 only development is there any consensus?? Are there any > real arguments for being "explicit" with inheriting from "object"?? I > have > to say that I have not yet found the allusion to Zen to be explicit not > convincing. > As you note, the (object) was needed in Python2 to make it a "New Style" class, while in Python 3 that is the only style class that exists. In Python3, it is purely optional, and its presence is merely stylistic. The big question comes, are you working on a project or with a group of programmers used to dealing with Python2, so have the habit of the explicit reference to object, or is the project brand new with fresh developers, for whom the (object) would be just noise? I suspect that most new projects will actually fall somewhat in the middle, not needing to be compatible with Python 2 (let it rest in peace) but with some developers still with older habits, and a decision needing to be made as to which style is more readable TO THAT TEAM. There of course are also 'zealots' who are frustrated by the extremely slow demise of Python 2 and want to purge its memory from the style and therefore want to insist on dropping the now unneeded (object) from the definition, being afraid of Python 2 saying "I'm not dead yet", and wanting to try to hammer the nails in the coffin to be rid of it. -- Richard Damon From PyTutor at DancesWithMice.info Sun Jun 7 16:08:33 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Mon, 8 Jun 2020 08:08:33 +1200 Subject: [Tutor] Beginner Noob In-Reply-To: <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com> References: <023d01d63b98$22f22290$68d667b0$@gmail.com> <4hR96L3APaPhJ9MISGPuaIR6lsR1iKq0e37q9gvLZiehZvolOQ6BLAAKygVRzFkOustUCBMZFT_dSPiH4OGSYSe96ZdZgz3fjmYtTD0Au2g=@protonmail.com> Message-ID: On 8/06/20 4:58 AM, alexkleider via Tutor wrote: > ??????? Original Message ??????? > On Sunday, June 7, 2020 5:51 AM, David wrote: > >> On Sat, 6 Jun 2020 at 18:39, DL Neil via Tutor tutor at python.org wrote: >> >>> There is a MicroPython which works well on Raspberry Pi SBCs, whereas >>> there is a version of C which is native to the Arduino. >> >> May I offer a small correction, because this seems a bit misleading about >> the MicroPython project [1]. The whole point of MicroPython is that it >> has been designed to run directly on a tiny microcontroller, with no >> operating system required, and is optimised for doing so at the cost >> of other performance aspects. It can also run on Linux, for development. >> >> Raspberry Pi runs Linux. So although you can run MicroPython on a >> Raspberry Pi, you generally wouldn't, because there's no point, and >> any of the other Linux varieties of Python will probably perform better, >> generally speaking, because they will exploit all the advantages provided >> by the operating system. >> >> [1] https://micropython.org/ > > A few comments that might be pertinent (from another grey head _without_ a tech background.) > > There was a tutorial given at the San Francisco Python MeetUp group at what may have been the last meeting they had before the lock-down. > It was about microPython on the arduino. You might wish to look that up- there may be info related to it on line. I can try to look up contacts who might be helpful if you wish. > I've used the RPi a lot- it is very Python orientated and I doubt that you'd run into difficulties because of limited resources, especially if you got a late model one- each model has more ports, more memory, faster processor, ... > It's easy to run the Pi 'headless' so no need for setting up monitor, keyboard, mouse etc (as long as you are comfortable with SSH and the terminal command line.) > Be happy to discuss further (on or off list, the latter perhaps being more appropriate since it will be mostly about the Pi rather than Python.) Thanks both! Yes, I had taken a language-centric approach to advising the OP. Of course, were I paid, I might say "only Python, everywhere"... For this reason and the helpful added detail, eg SSH/'headless', IMHO stay *on-list*, for now. If the microPython/SBC traffic increases to the point of 'irritation', it will demonstrate demand and thereby justify a separate list, eg Python on SBCs. That said, there are other sources for such information and discussion. PS I'm formulating another in my "Friday Finking" philosophical discussions (on the 'main' Python list) which will hark-back to playing with 4-bit processors during the '70s, and hopes-and-dreams perhaps lost or misplaced mean-time... -- Regards =dn From alan.gauld at yahoo.co.uk Sun Jun 7 16:36:34 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 7 Jun 2020 21:36:34 +0100 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: <20200607175133.GC10604@Dream-Machine1> References: <20200607175133.GC10604@Dream-Machine1> Message-ID: On 07/06/2020 18:51, boB Stepp wrote: > So, for Python 3 only development is there any consensus? Are there any > real arguments for being "explicit" with inheriting from "object"? No idea, but I never use object these days. I stopped using Pyhon 2.7 for anything (other than answering other peoples questions) about 2 years ago... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Sun Jun 7 16:37:04 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 7 Jun 2020 15:37:04 -0500 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: References: <20200607175133.GC10604@Dream-Machine1> Message-ID: <20200607203704.GD10604@Dream-Machine1> On Sun, Jun 07, 2020 at 12:15:03PM -0600, Mats Wichmann wrote: >Here's my claim: listen to pylint, or someday you'll end up having to >defend why you're doing something pylint complains about. :) Tools >like Pylint and Black are pretty opinionated (although Black is so >opinionated that you can't override most of its choices, while Pylint is >almost infintely configurable), and sometimes it's just easier to go >with the flow. As you are obviously remembering, I have recently started "playing" with Black and Pylint. Black I don't even try to fight while I am using it as, I probably cannot change its behavior -- the whole point of using it, really. But Pylint, which has so many possibilities for customization, has generated a real reluctance on my part to "tweak" it: 1) I generally don't feel confident that I have enough knowledge and background to make the tweaks without either asking on this forum first and/or doing online research. 2) In line with (1) it *has* caught misconceptions on my part even though (at the time) I was *certain* that it was a silly complaint. See, for instance, my post last night about an unneeded comprehension. I had forgotten which data file format I was currently dealing with and did not realize I could use dict() directly, something that, I am sure, never happens to you pros. ~(:>)) 3) And it has been quite useful in finding things I had absolutely no clue about and needed to look up and learn. 4) *If* I *do* reach the "full confidence" level to make a tweak then I have to give careful consideration as to whether I want to make the tweak applicable to all of my projects -- past, present and future -- or if I want to make it more narrowly applicable. This creates a certain reluctance when it is usually quicker to just change the code. A good example of this would be something like "with open(filename) as f". There will surely follow a complaint about the single letter variable even though I don't think it will cause any future person misunderstanding. 5) So your comment "...and sometimes it's just easier to go with the flow" seems to dominate for me. All in all though I believe Pylint and company are proving (on balance) helpful to my learning and preventing mistakes. -- Wishing you only the best, boB Stepp From jf_byrnes at comcast.net Sun Jun 7 10:38:34 2020 From: jf_byrnes at comcast.net (Jim) Date: Sun, 7 Jun 2020 09:38:34 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On 6/7/20 4:07 AM, Peter Otten wrote: > Jim wrote: > >> You certainly know more about this than I do, but I wonder about the >> conclusion that xclip is not found. > > I don't know much, "qt tried as last resort" is my interpretation of the > latest pandas code, without actually running it. >> I don't think I need QT any more so I am going to stop trying to figure >> this out and try to finish the script I was working on. I do plan on >> coming back and see if there is a different solution other than deleting >> PyQt5. > > Did you try invoking > > pandas.io.clipboard.set_clipboard("xclip") > > before pasting? No unfortunately I did not. I wanted to get back to working on the script that exposed this mess so when deleting the QT stuff worked I just moved on. Once I get that script running I plan on re-installing QT and see what happens. Regards, Jim From alan.gauld at yahoo.co.uk Sun Jun 7 16:41:42 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 7 Jun 2020 21:41:42 +0100 Subject: [Tutor] Beginner Noob In-Reply-To: References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: I thought I'd already sent this but it doesn't appear to have arrived... On 06/06/2020 09:38, DL Neil via Tutor wrote: > There is a MicroPython which works well on Raspberry Pi SBCs, whereas > there is a version of C which is native to the Arduino. Off topic but I'm curious about a native C for Arduino. The basic development IDE for Arduino comes with a C++ compiler. What is the "native C" and why would anyone use it given that C++ is almost a complete superset of C? What is the advantage? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PyTutor at danceswithmice.info Sun Jun 7 16:51:05 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 8 Jun 2020 08:51:05 +1200 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: References: <20200607175133.GC10604@Dream-Machine1> Message-ID: On 8/06/20 7:35 AM, Richard Damon wrote: > On 6/7/20 1:51 PM, boB Stepp wrote: >> Now in "4.1 Classes" at >> https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/01_Class.html. >> >> >> Basic question for Python 3 only development:? Is it better style to use >> "class ClassName:" or "class ClassName(object):"?? Beazley uses the >> former >> in this material (so far).? Other readings online (no citations handy) >> prefer being explicit with the latter.? I note that pylint prefers >> omitting >> "(object)", calling it "useless-object-inheritance". >> >> I realize that if I am trying to write code compatible with both Python 2 >> and 3 that I need to explicitly inherit from "object". >> >> So, for Python 3 only development is there any consensus?? Are there any >> real arguments for being "explicit" with inheriting from "object"?? I >> have >> to say that I have not yet found the allusion to Zen to be explicit not >> convincing. >> > As you note, the (object) was needed in Python2 to make it a "New Style" > class, while in Python 3 that is the only style class that exists. > > In Python3, it is purely optional, and its presence is merely stylistic. > The big question comes, are you working on a project or with a group of > programmers used to dealing with Python2, so have the habit of the > explicit reference to object, or is the project brand new with fresh > developers, for whom the (object) would be just noise? > > I suspect that most new projects will actually fall somewhat in the > middle, not needing to be compatible with Python 2 (let it rest in > peace) but with some developers still with older habits, and a decision > needing to be made as to which style is more readable TO THAT TEAM. > > There of course are also 'zealots' who are frustrated by the extremely > slow demise of Python 2 and want to purge its memory from the style and > therefore want to insist on dropping the now unneeded (object) from the > definition, being afraid of Python 2 saying "I'm not dead yet", and > wanting to try to hammer the nails in the coffin to be rid of it. I enjoy being made to step-back and think... I'm about as far from being a 'zealot' for lint-ing as one can get, but have a keen appreciation for the psychology of consistency (both amongst a team and 'within' an individual - without that, lies madness!) These days I'm exclusively using Python3 and think that all active-clients and their project have been upgraded - but that from 'common sense' rather than any agenda to 'kill' Python2. Having come from those days (when men were men, knights were bold, ...) my 'muscle-memory' adds parentheses when defining ClassNames (ie without conscious thought). I have learned not to add "object" between (he's 'slow', but usually he gets 'there'!). However, there is still some vestige of recognition in my mind, that the parentheses 'make' it a class (wrong!) - or make it easier to recognise the code-line as-such (which assumes reading-mode cf asking one's IDE to locate/display the class definition). From the other perspective, a sub-class *must* use a parenthetical expression: class LinksRegister( collections.UserList ): cf class LinksRegister(): # being consistent!? class LinksRegister: # being precise!? Hence the unadorned option, whilst 'the most correct', looks slightly odd (to me). Cue: gather around and sing "Tradition"* Pycharm (in as much as it embodies PEPs, linters, and style) whilst typing a new class definition offers "':' expected". If empty parentheses are added, it then instructs "Remove redundant parentheses". Does a touch-typist (a real man, a knight, ...) even notice these messages? Nah! (Woe is me...) * Fiddler on the Roof https://www.imdb.com/title/tt0067093/?ref_=fn_al_tt_1 -- Regards =dn From 1611kjb at gmail.com Sun Jun 7 17:54:32 2020 From: 1611kjb at gmail.com (Michael Deslippe) Date: Sun, 7 Jun 2020 21:54:32 +0000 Subject: [Tutor] Beginner Noob In-Reply-To: References: <023d01d63b98$22f22290$68d667b0$@gmail.com> Message-ID: <034701d63c3b$495c96b0$dc15c410$@Domain> Thank you very much for the input. Somewhere around 5-10 years ago Microsoft was deciding whether to retain VB or drop support all together. After much debate they decided VB could be as structured and modern as any language and that they were going to move in that direction. I had moved away from programming by then and never followed what has happened with the language. I remember Microsoft's first foray into improving BASIC when they introduced Qbasic. It was well received (I still have the components for it) but it wasn't much of an evolutionary leap, however it helped the average MS-DOS and early Windows user deal with quick programming. Sounds like I may jump on the Python bandwagon and slow my work on C# until I need it, or I have gone the distance with Python. I don?t believe anyone ever masters an active evolving language, but I believe their are users and there are inventors. I user learns enough to become proficient in solving problems in other environments requiring programming, an inventor is always looking for better ways to use the tool and rewrite code they?ve already written to make it the best they can. I?m the former. I?ve been the latter in other stages of my growth, but now most things have me living with practicality. Thanks for the input, it?s been helpful. ?-Mike -----Original Message----- From: Tutor On Behalf Of Alan Gauld via Tutor Sent: Saturday, June 6, 2020 3:59 AM To: tutor at python.org Subject: Re: [Tutor] Beginner Noob On 06/06/2020 01:19, 1611kjb at gmail.com wrote: > Whew, I'm long winded, I say all that to ask, what are the advantages > to jumping over to Python from VB? Python is a more modern language with more powerful data structures and language constructs. Although with modern VB.Net that's less of an argument. Python also has an awesome standard library and third-party supported ecosystem. > I am simultaneously working on C# and > wondering if it's worth taxing myself to learn another language. Every language teaches lessons that you can apply in every other language. Some teach more than others - Lisp, Smalltalk, Prolog, etc C# is a traditional language in the same vein as C/C++/Pascal/Java. It's very good for large projects (100k+ lines) involving many programmers. But it requires a lot of planning and design at a detailed level to use effectively. Python is designed for rapid implementation. It's not as fast in execution but it can be thrown together in a more experimental fashion. Before I retired I used Python as a prototyping language before handing designs over to our contractor programmers who were using Java. Of course Python can be used in production code too with a little extra care. VB sits somewhere between those two on the technology continuum Faster to write than C#, not as fast as Python(unless you are building GUIs) but not as powerful as C# either. (I may be wrong but I get the impression that VB.Net is slowly fading away. C# has closed the gap to the point where VB's advantages have been eroded.) > platform for K12 education, Arduino controllers and Raspberry PI computers. > They all seem to like Python and C, C++ and C#. I'm an old retired guy > stretching the grey muscles and just wondering if this is a good way > to apply myself. Thanks for any input. I'm sure I'll br here a lot. Python is used in all these areas and is generally considered easier to learn than C# and certainly C++. I would only recommend C++ if you are tinkering at the machine level - its the natural partner for an Arduino for example. C# (and Java) are similar to C++ but more focused on higher level application code. C++ compiles to native machine code. All the others compile to bytecode which is then interpreted. For normal human interactive programs it makes little difference on modern computers. If you are writing a high data volume server or a piece of hardware interface then speed may become an issue and c++ wins. But at the expense of much harder to write, test and debug code. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From 1611kjb at gmail.com Sun Jun 7 18:16:27 2020 From: 1611kjb at gmail.com (Michael Deslippe) Date: Sun, 7 Jun 2020 22:16:27 +0000 Subject: [Tutor] =?windows-1252?q?=93Native_C=94?= Message-ID: I?m just guessing here, but ?advantage? may be the wrong view. What is it that you call ?Native C?? From my view, before any versions came along, ?C? was the foundation for Unix and came packaged with virtually and distribution), thus development in C became natural as you merely had to reach out and touch it. As versions of Unix developed, C morphed right along with it. Again, I?m an old guy, but last I knew, the winner came out as Linux and Linux wasn?t given a native copy of C. Arduino is founded on rudimentary control and so it leans towards rudimentary answers. Arduino doesn?t actually understand all of C but only a subset of the language as that?s all that is necessary. Creating subsets of different versions simply to extract the subset required by Arduino would be a lot of work with no tangible benefit. Raspberry Pi however, uses the full spectrum of C and, as one would expect, has developed all the flavors of C, C++ and C#. However, if you understand the needs of Arduino, you can write programs from any flavor just so long as you and the compiler don?t touch things Arduino doesn?t understand. As I understand it, Arduino big brother, the 2560 Mega understands more than the Uno and I understand they are working on several renditions surpassing the Mega. So we may see broader acceptance of C variants before too long. ---Mike I thought I'd already sent this but it doesn't appear to have arrived... On 06/06/2020 09:38, DL Neil via Tutor wrote: > There is a MicroPython which works well on Raspberry Pi SBCs, whereas > there is a version of C which is native to the Arduino. Off topic but I'm curious about a native C for Arduino. The basic development IDE for Arduino comes with a C++ compiler. What is the "native C" and why would anyone use it given that C++ is almost a complete superset of C? What is the advantage? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From robertvstepp at gmail.com Sun Jun 7 23:02:50 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 7 Jun 2020 22:02:50 -0500 Subject: [Tutor] What are the benefits of template or abstract base classes? Message-ID: <20200608030250.GF10604@Dream-Machine1> Now in "4.2 Inheritance" at https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html class TableFormatter: def headings(self, headers): ''' Emit the table headings. ''' raise NotImplementedError() def row(self, rowdata): ''' Emit a single row of table data. ''' raise NotImplementedError() with the comment: "This class does nothing, but it serves as a kind of design specification for additional classes that will be defined shortly. A class like this is sometimes called an ?abstract base class.?" As the exercises in this section progressed I had to write the classes TextTableFormatter(TableFormatter), CSVTableFormatter(TableFormatter) and HTMLTableFormatter(TableFormatter) for which each class had its custom implementations of the headings and row methods. I don't see much real benefit to having the original TableFormatter class as used here. Am I wrong to think this? At best it gives a single place to look to remind a coder what methods are intended to be implemented for all subclasses, but does not constrain the coder to do so. OTOH, this inspired me to read up a bit on actual abstract base classes (ABC), which *do* force the coder to implement the methods of the ABC or it will not allow one to instantiate the method-deficient subclass. I can see some benefit to this approach. Of course, Beazley may be planning on heading in the true ABC direction later in the material. What are your thoughts? Perhaps a fuller explanation for noobie boB? -- Wishing you only the best, boB Stepp From __peter__ at web.de Mon Jun 8 08:51:27 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 08 Jun 2020 14:51:27 +0200 Subject: [Tutor] What are the benefits of template or abstract base classes? References: <20200608030250.GF10604@Dream-Machine1> Message-ID: boB Stepp wrote: > Now in "4.2 Inheritance" at > https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html > > class TableFormatter: > def headings(self, headers): > ''' > Emit the table headings. > ''' > raise NotImplementedError() > > def row(self, rowdata): > ''' > Emit a single row of table data. > ''' > raise NotImplementedError() > > with the comment: > > "This class does nothing > What are your thoughts? Dunno. Maybe writing code that does nothing is an art form, like poems or songs... and mypy is your arbiter elegantiarum. From alan.gauld at yahoo.co.uk Mon Jun 8 11:29:32 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 8 Jun 2020 16:29:32 +0100 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: <20200608030250.GF10604@Dream-Machine1> References: <20200608030250.GF10604@Dream-Machine1> Message-ID: I posted this earlier today but it seems to have vanished into bit dust... trying again... On 08/06/2020 04:02, boB Stepp wrote: > implementations of the headings and row methods. I don't see > much real benefit to having the original TableFormatter class > as used here. Am I wrong to think this? You may be right in this specific case and, as you say, Beazley is probably going to add features that make it more useful. But in the general case abstract classes are the fundamental building blocks of most OOP systems. You generalize the entities within the system into a smallish set of interacting abstract classes. You build the system using those abstract classes. In that way the entire core logic of your system is expressed in abstract terms. Then you start building the concrete versions of those abstractions and slotting them into the system. You don't need to modify the abstract code because the objects are polymorphic and will respond exactly like the abstract versions (except they actually do something!). So abstract classes are of limited value in isolation, it's when you get a group of them acting according to some pattern of behaviour that they become useful. Think about a GUI. It has Window objects(abstract) and events (abstract) and possibly a Canvas(possibly abstract). You can then design how window objects interact with each other and with events and represent themselves on a canvas in purely abstract terms. Then start building concrete widgets as subclasses of window. Create real events(mouse, keyboard, network etc) and real canvases(screen, printer, virtual) etc. The GUI framework will use these new classes with no new work. And that's how almost all real-world GUI frameworks are built. (The mixin style of multiple inheriance OOP is also based on the idea of abstract mixins that you then replace with concrete variations on the theme. But with mixins its normally a case of partially implemented classes rather than pure abstracts - what C++ calls virtual classes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jf_byrnes at comcast.net Mon Jun 8 12:59:54 2020 From: jf_byrnes at comcast.net (Jim) Date: Mon, 8 Jun 2020 11:59:54 -0500 Subject: [Tutor] pandas.to_clipboard() copies nothing In-Reply-To: References: Message-ID: On 6/7/20 9:38 AM, Jim wrote: > On 6/7/20 4:07 AM, Peter Otten wrote: >> Jim wrote: >> >>> You certainly know more about this than I do, but I wonder about the >>> conclusion that xclip is not found. >> >> I don't know much, "qt tried as last resort" is my interpretation of the >> latest pandas code, without actually running it. > > > >>> I don't think I need QT any more so I am going to stop trying to figure >>> this out and try to finish the script I was working on. I do plan on >>> coming back and see if there is a different solution other than deleting >>> PyQt5. >> >> Did you try invoking >> >> pandas.io.clipboard.set_clipboard("xclip") >> >> before pasting? > > No unfortunately I did not. I wanted to get back to working on the > script that exposed this mess so when deleting the QT stuff worked I > just moved on. Once I get that script running I plan on re-installing QT > and see what happens. > Ok, so I reloaded PyQt5, here's what happened: (env36) jfb at jims-mint18 ~ $ pip install PyQt5 Collecting PyQt5 Using cached PyQt5-5.15.0-5.15.0-cp35.cp36.cp37.cp38-abi3-manylinux2014_x86_64.whl (76.6 MB) Collecting PyQt5-sip<13,>=12.8 Using cached PyQt5_sip-12.8.0-cp36-cp36m-manylinux1_x86_64.whl (277 kB) Installing collected packages: PyQt5-sip, PyQt5 Successfully installed PyQt5-5.15.0 PyQt5-sip-12.8.0 The results of running the test file: (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb. Aborted Here I tried adding set_clipboard: (env36) jfb at jims-mint18 ~ $ python /home/jfb/Dev/Python/test_csv_file.py Traceback (most recent call last): File "/home/jfb/Dev/Python/test_csv_file.py", line 11, in pandas.io.clipboard.set_clipboard("xclip") AttributeError: module 'pandas.io' has no attribute 'clipboard' (env36) jfb at jims-mint18 ~ $ I googled the error and found references to it going back to 2013. Most solutions were aimed at people developing with PyQt, add debug statements etc. Some seemed to aimed at users and suggested tinkering with simlinks, paths and installing additional packages. Most of them I did not fully understand. Anyway I have my solution. Delete PyQt5 and the problem goes away. If I ever want to use QT again, setup a new VE and never run pandas in it. Regards, Jim From robertvstepp at gmail.com Mon Jun 8 14:00:53 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 8 Jun 2020 13:00:53 -0500 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: References: <20200608030250.GF10604@Dream-Machine1> Message-ID: On Mon, Jun 8, 2020 at 10:29 AM Alan Gauld via Tutor wrote: > > I posted this earlier today but it seems to have vanished into > bit dust... trying again... I did receive the original email prior to it appearing on the Tutor Archive. > But in the general case abstract classes are the fundamental building > blocks of most OOP systems. You generalize the entities within the > system into a smallish set of interacting abstract classes. You build > the system using those abstract classes. In that way the entire core > logic of your system is expressed in abstract terms. Then you start > building the concrete versions of those abstractions and slotting them > into the system. You don't need to modify the abstract code because the > objects are polymorphic and will respond exactly like the abstract > versions (except they actually do something!). > > So abstract classes are of limited value in isolation, it's when you get > a group of them acting according to some pattern of behaviour that they > become useful. Think about a GUI. It has Window objects(abstract) and > events (abstract) and possibly a Canvas(possibly abstract). You can then > design how window objects interact with each other and with events and > represent themselves on a canvas in purely abstract terms. Then start > building concrete widgets as subclasses of window. Create real > events(mouse, keyboard, network etc) and real canvases(screen, printer, > virtual) etc. The GUI framework will use these new classes with no new > work. And that's how almost all real-world GUI frameworks are built. Hmm. Then ABCs seem quite useful. I wonder why I normally only see mention of them as being advanced features? If I am following you they would seem very useful for anything beyond small, simple OO programs. Sounds like something that I probably should investigate if I ever get a handle on the basic class writing stuff. > (The mixin style of multiple inheriance OOP is also based on the > idea of abstract mixins that you then replace with concrete > variations on the theme. But with mixins its normally a case > of partially implemented classes rather than pure abstracts > - what C++ calls virtual classes. So these concepts are language-agnostic and broadly used? Thanks! -- boB From robertvstepp at gmail.com Mon Jun 8 14:10:21 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 8 Jun 2020 13:10:21 -0500 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: References: <20200608030250.GF10604@Dream-Machine1> Message-ID: On Mon, Jun 8, 2020 at 7:52 AM Peter Otten <__peter__ at web.de> wrote: > > boB Stepp wrote: > > > Now in "4.2 Inheritance" at > > https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html > > > > class TableFormatter: > > def headings(self, headers): > > ''' > > Emit the table headings. > > ''' > > raise NotImplementedError() > > > > def row(self, rowdata): > > ''' > > Emit a single row of table data. > > ''' > > raise NotImplementedError() > > > > with the comment: > > > > "This class does nothing > > > What are your thoughts? > > Dunno. Maybe writing code that does nothing is an art form, like poems or > songs... and mypy is your arbiter elegantiarum. Totally unexpected, quirky response! Who shall reign supreme in directing my cyber-court: Black, MyPy or Pylint? Pylint critiques seemingly every choice, but will back down if challenged. MyPy only judges a subset of cyberlife. And Black judges with an iron hand. Perhaps off with him to the Coliseum fights to perish unless further deemed worthy? ~(:>)) -- boB From __peter__ at web.de Mon Jun 8 16:59:50 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 08 Jun 2020 22:59:50 +0200 Subject: [Tutor] What are the benefits of template or abstract base classes? References: <20200608030250.GF10604@Dream-Machine1> Message-ID: boB Stepp wrote: > On Mon, Jun 8, 2020 at 7:52 AM Peter Otten <__peter__ at web.de> wrote: >> >> boB Stepp wrote: >> >> > Now in "4.2 Inheritance" at >> > https://dabeaz-course.github.io/practical->> > python/Notes/04_Classes_objects/02_Inheritance.html >> > >> > class TableFormatter: >> > def headings(self, headers): >> > ''' >> > Emit the table headings. >> > ''' >> > raise NotImplementedError() >> > >> > def row(self, rowdata): >> > ''' >> > Emit a single row of table data. >> > ''' >> > raise NotImplementedError() >> > >> > with the comment: >> > >> > "This class does nothing >> >> > What are your thoughts? >> >> Dunno. Maybe writing code that does nothing is an art form, like poems or >> songs... and mypy is your arbiter elegantiarum. > > Totally unexpected, quirky response! Who shall reign supreme in > directing my cyber-court: Black, MyPy or Pylint? Pylint critiques > seemingly every choice, but will back down if challenged. MyPy only > judges a subset of cyberlife. And Black judges with an iron hand. > Perhaps off with him to the Coliseum fights to perish unless further > deemed worthy? > ~(:>)) > I don't know Black; with pylint you can cheat a little and get a score of 10 for your perfect code, or you can cheat some more and get a score of 10 for your heap of crap. mypy on the other hand is open-ended. Start with TableFormatter, do you want to feed it Any? Of course not, so print_table(table: Table, formatter: TableFormatter) We've already established that the table consists of header and rows class Header: column_headers: Sequence[ColumnHeader] class Rows: rows: Iterator[Row] class Row: fields: Sequence[Field] class Field: def format(format: FieldFormat) -> str class StrField, FloatField, DatetimeField, YouNameItField,... Table: rows: Rows header: Header That looks safe except that we stated that fields are formatted as str. What if in addition to csv and text we want to write a binary format? class Field: def format(format: FieldFormat) -> SerializedField We are starting to get robust. We just need to come up with a FieldFormat that works for all subclasses. That can't be hard, so let's look elsewhere. David used short strings to specify the Formatter -- not very robust, and Python has enums since ... when? So class TableFormatterType(enum.Enum): text = "txt" csv = "csv" Not as good as the http guys with their Referer, but still nice. Having another glimpse at our zoo of fields, how can we instantiate the right subclass? We certainly need a RowFieldFactory and a ColumnHeaderFactory. While we're at it, a TableFormatterFactory to cope with our CSVTableFormatter, and TextTableFormatter is de rigueur. Are we done? Oh dear, do you think our table springs into existence out of nowhere? I'll leave the details of the TableBuilder, or, let's be precise, FormatableTableBuilder (or is it PrintableFormatableTableBuilder?) as an exercise for the reader... That said, I feel a bit uneasy about the FieldFormat, we should do it right and use a FieldFormatter instead. That gives us flexibility; one formatter per field type, composable for width, alignment, color, font, all governed by a nice little FieldFormatterFactory... From cs at cskk.id.au Mon Jun 8 04:58:48 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 8 Jun 2020 18:58:48 +1000 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: <20200608030250.GF10604@Dream-Machine1> References: <20200608030250.GF10604@Dream-Machine1> Message-ID: <20200608085848.GA58604@cskk.homeip.net> On 07Jun2020 22:02, boB Stepp wrote: >Now in "4.2 Inheritance" at >https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html > >class TableFormatter: > def headings(self, headers): > ''' > Emit the table headings. > ''' > raise NotImplementedError() >.... >with the comment: > >"This class does nothing, but it serves as a kind of design specification >for additional classes that will be defined shortly. A class like this is >sometimes called an ?abstract base class.?" I'd note that this code may well predate the ABC stdlib classes. Or Beaz' use of them. So this class to my eye has two benefits: - like the stdlib ABC or any abstract base class in general, it lets you outline the methods you intend to provide and describe their semantics/behaviour - just specifying things like this helps makes things clear in your mind _before_ you go to write the code - like the recommended way to write ABC methods, these methods explode in your face if you haven't overridden them. This is handy if you forget things. And if you're doing test driven development, or just having a decent test suite, this will aid in having those tests fail if the implementation is incomplete >OTOH, this inspired me to read up a bit on actual abstract base classes >(ABC), which *do* force the coder to implement the methods of the ABC or it >will not allow one to instantiate the method-deficient subclass. I can see >some benefit to this approach. Of course, Beazley may be planning on >heading in the true ABC direction later in the material. That is the nice thing about the stdlib ABC stuff: an unoverridden @abstractmethod will actually cause the subclass definition to fail, effectively like a compile time failure. Instead of some explosion at runtime (ideally during testing). However, just having an abstract base class like Baez' one is probably good design practice, particularly if you're going to make a few subclasses. Cheers, Cameron Simpson From cs at cskk.id.au Sun Jun 7 22:15:32 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 8 Jun 2020 12:15:32 +1000 Subject: [Tutor] Python 3 only: Better to use implicit or explicit "object" in class statements? In-Reply-To: <20200607175133.GC10604@Dream-Machine1> References: <20200607175133.GC10604@Dream-Machine1> Message-ID: <20200608021532.GA17546@cskk.homeip.net> On 07Jun2020 12:51, boB Stepp wrote: >prefer being explicit with the latter. I note that pylint prefers >omitting >"(object)", calling it "useless-object-inheritance". My lint script runs pylint with these items disabled: pylint_disable=bad-whitespace,bad-indentation,bad-continuation,invalid-name,useless-object-inheritance Now, I might start stripping these back some more since I autoformat code more vigorously these days. But these complaints caused more noise than their cleanup warranted. For me. >I realize that if I am trying to write code compatible with both Python 2 >and 3 that I need to explicitly inherit from "object". > >So, for Python 3 only development is there any consensus? Are there any >real arguments for being "explicit" with inheriting from "object"? I have >to say that I have not yet found the allusion to Zen to be explicit not >convincing. If I'm writing shiny new modules (thus, generally for Python 3 only unless I have some special purpose in mind), I omit the (object). When maintaining legacy modules which might still be in play for Python 2 programmes, I still use (object). because I don't need to break such modules gratuitously. Cheers, Cameron Simpson From hromero1231 at gmail.com Mon Jun 8 23:21:29 2020 From: hromero1231 at gmail.com (harold Romero) Date: Mon, 8 Jun 2020 23:21:29 -0400 Subject: [Tutor] I need help solving this Message-ID: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com> My program needs to have two input statements. One will ask for the shape and the other for the location. The shape is limited to either a circle or a square. If the user selects a circle the program needs to ask the user for the pen color. The choices are red, blue or yellow. All of the pen colors will determine a specific fill color. Explore online to find a new fill color. For instance if the user selects red as the pen color, the fill color will be pink (or whatever other color you want). If the user selects a square the program needs to ask the user for a fill color. The choices are red, blue or yellow. These colors will determine the pen color. For instance if the user selects blue for the fill color, the pen color can be green (or whatever other color you choose. The location is limited to Top Left, Top Right, Bottom Left and Bottom Right. If the user enters Top Left, then the pen size must be 3. If the user enters Top Right, then pen size must be 5. If the user enters Bottom Left, then the pen size must be 7. Finally if the user enters Bottom Right then the pen size must be 9. Im having a problem with have all four being drawn I just want one From alan.gauld at yahoo.co.uk Tue Jun 9 04:13:11 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 9 Jun 2020 09:13:11 +0100 Subject: [Tutor] I need help solving this In-Reply-To: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com> References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com> Message-ID: On 09/06/2020 04:21, harold Romero wrote: > My program needs to have two input statements. One will ask for the shape and the other for the location. > Im having a problem with have all four being drawn I just want one Without seeing your code we cannot begin to guess what you have done wrong. But the intention of the exercise is obviously for you to capture the input data and other choices as variables then draw one shape using those variables as parameters. So there really shouldn't be 4 of them! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Tue Jun 9 13:42:18 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 9 Jun 2020 12:42:18 -0500 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: <20200608085848.GA58604@cskk.homeip.net> References: <20200608030250.GF10604@Dream-Machine1> <20200608085848.GA58604@cskk.homeip.net> Message-ID: On Mon, Jun 8, 2020 at 11:35 PM Cameron Simpson wrote: > > On 07Jun2020 22:02, boB Stepp wrote: > >Now in "4.2 Inheritance" at > >https://dabeaz-course.github.io/practical-python/Notes/04_Classes_objects/02_Inheritance.html > > > >class TableFormatter: > > def headings(self, headers): > > ''' > > Emit the table headings. > > ''' > > raise NotImplementedError() > >.... > >with the comment: > > > >"This class does nothing, but it serves as a kind of design specification > >for additional classes that will be defined shortly. A class like this is > >sometimes called an ?abstract base class.?" > > I'd note that this code may well predate the ABC stdlib classes. Or > Beaz' use of them. So this class to my eye has two benefits: I did not consider this. Plus now that I am being better exposed to the design benefits of doing ABCs -- the above or the now standard library version -- I can now see why he wanted to make this point. > - like the stdlib ABC or any abstract base class in general, it lets you > outline the methods you intend to provide and describe their > semantics/behaviour - just specifying things like this helps makes > things clear in your mind _before_ you go to write the code Another point that did not occur to me. > - like the recommended way to write ABC methods, these methods explode > in your face if you haven't overridden them. This is handy if you > forget things. And if you're doing test driven development, or just > having a decent test suite, this will aid in having those tests fail > if the implementation is incomplete > > >OTOH, this inspired me to read up a bit on actual abstract base classes > >(ABC), which *do* force the coder to implement the methods of the ABC or it > >will not allow one to instantiate the method-deficient subclass. I can see > >some benefit to this approach. Of course, Beazley may be planning on > >heading in the true ABC direction later in the material. > > That is the nice thing about the stdlib ABC stuff: an unoverridden > @abstractmethod will actually cause the subclass definition to fail, > effectively like a compile time failure. Instead of some explosion at > runtime (ideally during testing). I had played with Beazley's example and noticed it would allow me to instantiate a subclass, but would blow up if I did not override the methods and tried to use them. > However, just having an abstract base class like Baez' one is probably > good design practice, particularly if you're going to make a few > subclasses. Your and Alan's comments have given me the sort of feedback I was hoping for. This OOP paradigm that I have mostly been avoiding I find hard going in how to design and setup an approach. Already written classes I can usually parse out, but the why's of how the classes are chosen and written I struggle with. Especially when what is being modeled is somewhat abstract, not a physical system like the trite Animal -> Mammal -> Dog/Cat, etc. type examples that are prevalent. For instance Beazley's chosen example is an excellent one for me to struggle with as it falls (in my mind) into the more abstract type system. How to divy that up into meaningful classes I find difficult. -- boB From adameyring at gmail.com Tue Jun 9 22:46:21 2020 From: adameyring at gmail.com (Adam Eyring) Date: Tue, 9 Jun 2020 22:46:21 -0400 Subject: [Tutor] I need help solving this In-Reply-To: References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com> Message-ID: If you set up your if statements correctly to respond to the user input, you should only get one output. e.g. i = input("(B)lue, (G)reen, (Y)ellow?") if i == "B": draw blue circle elif i == "G": draw green circle else: draw yellow circle AME On Tue, Jun 9, 2020 at 4:13 AM Alan Gauld via Tutor wrote: > On 09/06/2020 04:21, harold Romero wrote: > > My program needs to have two input statements. One will ask for the > shape and the other for the location. > > > Im having a problem with have all four being drawn I just want one > > Without seeing your code we cannot begin to guess what you have done > wrong. But the intention of the exercise is obviously for you to capture > the input data and other choices as variables then draw one shape using > those variables as parameters. So there really shouldn't be 4 of them! > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From masonchristine12 at gmail.com Tue Jun 9 22:29:11 2020 From: masonchristine12 at gmail.com (Christine Mason) Date: Wed, 10 Jun 2020 14:29:11 +1200 Subject: [Tutor] Can anyone help answer this? Message-ID: Given the following class definition: class Food: def __init__(self, name, taste): self.name = name self.taste = taste Write a function *createFood()* that takes a list of food items as argument and creates an instance of class Food for each of them. It then returns the list of instances that it has created. Each food item in the list that is passed as argument to *createFood() *is a tuple of the form ('name', 'taste'), so the list of food items might look like this: [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')] The function *createFood() *takes the two elements of each tuple and passes them to the initialiser of Food. It then collects the objects returned by the initialiser and adds them to the list that is returned by createFood(). DO NOT call the function From PyTutor at danceswithmice.info Wed Jun 10 04:09:20 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Wed, 10 Jun 2020 20:09:20 +1200 Subject: [Tutor] Can anyone help answer this? In-Reply-To: References: Message-ID: <3cc004f6-e00d-b87e-df02-ecb9b3127a34@DancesWithMice.info> On 10/06/20 2:29 PM, Christine Mason wrote: > Given the following class definition: > > class Food: > > def __init__(self, name, taste): > > self.name > > = name > > self.taste = taste > > Write a function *createFood()* that takes a list of food items as > argument and creates an instance of class Food for each of them. It then > returns the list of instances that it has created. > > Each food item in the list that is passed as argument to *createFood() *is > a tuple of the form ('name', 'taste'), so the list of food items might look > like this: > > [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')] > > The function *createFood() *takes the two elements of each tuple and > passes them to the initialiser of Food. It then collects the objects > returned by the initialiser and adds them to the list that is returned by > createFood(). > > DO NOT call the function Is this an homework assignment? If so, for which course - and if you can give us on-line references, that's a bonus! Assuming the above, we will be happy to *help* *you* find a solution. What code do you have so far? What results? Please copy-paste them into your reply. For example: - how do you instantiate an example of the Food class? - how will you loop through each of the foods in the input list?tuple? - how will you create, and then add, results to the output list? The last injunction is badly-expressed. I presume that you are to forward your work to be graded as a function - and only a function (a common methodology to ease the grading process). However, to test your code, as a function, you will need to call it from somewhere! Either add a temporary function-call for testing (and remember to remove it before handing-in), or have you already learned about TDD (Test-Driven Development), eg pytest, unittest, ...? -- Regards =dn From alan.gauld at yahoo.co.uk Wed Jun 10 05:44:55 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 10 Jun 2020 10:44:55 +0100 Subject: [Tutor] I need help solving this In-Reply-To: References: <0CCED70E-1727-4D48-9976-78669A47C7DF@gmail.com> Message-ID: On 10/06/2020 03:46, Adam Eyring wrote: > If you set up your if statements correctly to respond to the user input, > you should only get one output. e.g. > i = input("(B)lue, (G)reen, (Y)ellow?") > if i == "B": > draw blue circle > elif i == "G": > draw green circle > else: > draw yellow circle > Or even better just set the parameters in the if statement then draw the circle once at the end. That way you can guarantee you only ever draw one circle even if you somehow set more than one group of values.. col = input("(B)lue, (G)reen, (Y)ellow?") if col == "B": set blue values elif col == "G": set green values else: set yellow values draw_circle(values) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Wed Jun 10 05:51:33 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 10 Jun 2020 10:51:33 +0100 Subject: [Tutor] Can anyone help answer this? In-Reply-To: References: Message-ID: On 10/06/2020 03:29, Christine Mason wrote: > Given the following class definition: > > class Food: > > def __init__(self, name, taste): > self.name = name > self.taste = taste > > Write a function *createFood()* that takes a list of food items as > argument and creates an instance of class Food for each of them. It then > returns the list of instances that it has created. > > Each food item in the list that is passed as argument to *createFood() *is > a tuple of the form ('name', 'taste'), so the list of food items might look > like this: > > [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')] > > The function *createFood() *takes the two elements of each tuple and > passes them to the initialiser of Food. It then collects the objects > returned by the initialiser and adds them to the list that is returned by > createFood(). I really hate when students (and I assume is is a homework/tutorial exercise) get asked to write bad code. This function should be entirely unnecessary. The function for creating instances is the constructor - it's already written. We don't need another. And the Pythonic way of building lists is a list comprehension. So this whole exercise should be reduced to: food_list = [Food(t) for t in tuple_list] If we are going to teach objects lets use the objects! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From manpritsinghece at gmail.com Wed Jun 10 04:32:28 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Wed, 10 Jun 2020 14:02:28 +0530 Subject: [Tutor] Appropriate use of list comprehension Message-ID: Hi all , I just need to know that the way I have used to enter 3 names inside the list , entered through keyboard, using list comprehension is syntactically correct or not . Is there any other more efficient way to do this? Below is the code given : val = [input("enter name") for _ in range(3)] val will be the list consisting those 3 names entered through keyboard. Regards Manprit Singh From alan.gauld at yahoo.co.uk Wed Jun 10 08:26:50 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 10 Jun 2020 13:26:50 +0100 Subject: [Tutor] Appropriate use of list comprehension In-Reply-To: References: Message-ID: On 10/06/2020 09:32, Manprit Singh wrote: > I just need to know that the way I have used to enter 3 names inside the > list , entered through keyboard, using list comprehension is syntactically > correct or not . The best check for syntax is the Python interpreter. if its happy then the syntax is fine. You can try pylint and similar tools for more critical analysis. > Is there any other more efficient way to do this? > Below is the code given : > > val = [input("enter name") for _ in range(3)] Not more efficient no, but for production code you should wrap it in a try/except block and usually, when reading user input in real code, we need at least minimal data sanity checks. But you can wrap that in a function and use the function in the comprehension. It is a valid use of a comprehension if that's what you are asking. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Wed Jun 10 10:31:38 2020 From: __peter__ at web.de (Peter Otten) Date: Wed, 10 Jun 2020 16:31:38 +0200 Subject: [Tutor] Can anyone help answer this? References: Message-ID: Alan Gauld via Tutor wrote: > On 10/06/2020 03:29, Christine Mason wrote: >> Given the following class definition: >> >> class Food: >> >> def __init__(self, name, taste): >> self.name = name >> self.taste = taste >> >> Write a function *createFood()* that takes a list of food items as >> argument and creates an instance of class Food for each of them. It then >> returns the list of instances that it has created. >> >> Each food item in the list that is passed as argument to *createFood() >> *is >> a tuple of the form ('name', 'taste'), so the list of food items might >> look like this: >> >> [('curry', 'spicy'), ('pavlova', 'sweet'), ('chips', 'salty')] >> >> The function *createFood() *takes the two elements of each tuple and >> passes them to the initialiser of Food. It then collects the objects >> returned by the initialiser and adds them to the list that is returned by >> createFood(). > > I really hate when students (and I assume is is a homework/tutorial > exercise) get asked to write bad code. This function should be > entirely unnecessary. It were unnecessary if it should create a single instance. For a whole list I think it's fine -- except that the name is misleading. > The function for creating instances is the > constructor - it's already written. We don't need another. > > And the Pythonic way of building lists is a list comprehension. > So this whole exercise should be reduced to: > > food_list = [Food(t) for t in tuple_list] You forgot the * which I think is an advanced and even somewhat questionable feature. To go to the other end of the spectrum of possible solutions, the teacher may well see attempts like def create_food_list(pairs): for i in range(len(pairs)): name = pairs[i][0] taste = pairs[i][1] food = Food(name, taste) pairs[i] = food return pairs which gives opportunities to show - idiomatic iteration - tuple unpacking - good ways for a function to communicate with its caller. You may argue that this should have been taught before starting with custom objects... > If we are going to teach objects lets use the objects! From PyTutor at danceswithmice.info Wed Jun 10 16:41:13 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Thu, 11 Jun 2020 08:41:13 +1200 Subject: [Tutor] Can anyone help answer this? In-Reply-To: References: Message-ID: <1868d1f4-4098-a84a-9eb4-a8a6e5f77a03@DancesWithMice.info> On 10/06/20 9:51 PM, Alan Gauld via Tutor wrote: > I really hate when students (and I assume is is a homework/tutorial > exercise) get asked to write bad code. This function should be > entirely unnecessary. The function for creating instances is the > constructor - it's already written. We don't need another. ... > If we are going to teach objects lets use the objects! That's one of two reasons for requesting that such students (one imagines) provide the course/source information. Students routinely grumble about 'the difficulty of assignments' and not understanding their wording. That's one thing. However, when practicing professionals and other tutors have criticisms, could?should we do something about the very problem that @Alan exposes. That said, it can be difficult to comprehend, from a (?lost) student's struggles with a single assignment, the sequence of presentation the tutor is using. Let's take, for example, @boB's recent question on abc-s (that didn't actually use an abc). There are many ways to answer his question, but too many such 'answers' actually have the potential to confuse or even de-rail DaBeaz's chosen step-by-step approach. As mentioned to @boB (possibly privately) I have too much respect for that tutor to want to leap in and (arrogantly, appear to) 'correct' the methods he employs. Whereas, at the end of the course, if the trainee is still 'lost' and unable to exhibit a well-rounded understanding of Python, development, objects, OOP; that would be a different story! Which leads me to the other end of the spectrum: there are lazy tutors who simply copy questions and chuck them 'over the wall' at a class, without any pedagogical consideration or care (I've seen them AND fired 'em!). NB I'm not saying that applies in the case of the OP or of that Tutor! However, given the expertise available on-the-list, perhaps it would not be out-of-place to also adopt a r?le of helping tutors to improve their assignments, and thus, the quality of their training and commensurately, of the abilities of their graduates to use Python? -- Regards =dn From robertvstepp at gmail.com Wed Jun 10 20:37:35 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 10 Jun 2020 19:37:35 -0500 Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type annotation errors) In-Reply-To: <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info> References: <20200606014015.GQ23247@Dream-Machine1> <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info> Message-ID: On Sat, Jun 6, 2020 at 9:45 PM DL Neil via Tutor wrote: > Given that 'the other David' has been a trainer almost as long as I (but > he as a Python trainer - which I am (formally) not!), it seemed > reasonable teaching technique/planning that the course would build > further (per more-recent messages to this list). Perhaps the assertion > of it being a useful utility back-then, was somewhat premature, and > better applied to its 'final' iteration of development? I am more than two-thirds through. I could not stand the suspense, and skimmed through all of the remaining sections and exercises. I must report that at the end of the course the function under critique still returns either a list of dicts or a list of tuples depending on whether headers are present or not. Make of this what you will. -- boB From Richard at Damon-Family.org Wed Jun 10 22:03:33 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Wed, 10 Jun 2020 22:03:33 -0400 Subject: [Tutor] Pythonic Style Question Message-ID: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> Background: Long time programmer (started with punch cards) but fairly new to punch cards, but fairly new to Python. Working on a program that will be a moderate size program when done, and doing it in Python as it looks to be a reasonable choice, and a good learning experience. Decided to try running pylint on it to see what sort or 'Preferred Style' it would lead me to (might as well have something look over the code and critique it) (I know the weaknesses of Linters, but worth a shot) Getting a lot of coding style errors for module global variables that seem to be a reasonable way to do it, but figured I would ask to see if there is a more Pythonic method to do these. Example, application will have a number of settings stored in a configuration file, so I have a myconfig.py module that is called with the path to the config file, that uses configparser to read in the options and create a module global variable (config) that other parts of the system can import, and then query/set by accessing. pylint first complains that these 'constants' should be in ALL_CAPS (but they aren't constants, so I don't think they should be ALL_CAPS), and in the function that will set it up, complains of the global statement so it can access the module global. I could also create my own access wrappers to get/set options, that other modules will call, but I would think I would still need the module global (and making it _config to mark it as a non-global still gets all the warnings about the constant not being ALL_CAPS). Is there another better way to do this sort of thing? or is pylint just being over picky (as lints are prone to be) and I need to put a comment on the statement to tell pylint it is ok? -- Richard Damon From PyTutor at danceswithmice.info Wed Jun 10 22:11:01 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Thu, 11 Jun 2020 14:11:01 +1200 Subject: [Tutor] Critiquing a function exercise from dabeaz (Was: Type annotation errors) In-Reply-To: References: <20200606014015.GQ23247@Dream-Machine1> <3528ca93-0626-c95d-f922-f548d06b04aa@DancesWithMice.info> Message-ID: On 11/06/20 12:37 PM, boB Stepp wrote: > On Sat, Jun 6, 2020 at 9:45 PM DL Neil via Tutor wrote: > >> Given that 'the other David' has been a trainer almost as long as I (but >> he as a Python trainer - which I am (formally) not!), it seemed >> reasonable teaching technique/planning that the course would build >> further (per more-recent messages to this list). Perhaps the assertion >> of it being a useful utility back-then, was somewhat premature, and >> better applied to its 'final' iteration of development? > > I am more than two-thirds through. I could not stand the suspense, > and skimmed through all of the remaining sections and exercises. I > must report that at the end of the course the function under critique > still returns either a list of dicts or a list of tuples depending on > whether headers are present or not. Make of this what you will. Perhaps then you should first finish the course, and then figure-out his 'what's next'. Possibly the story continues? [by then you will have basic Python objectives achieved] Failing that, revert and in a new msg/thread re-ask the question - perhaps stating the problem as a user request or series of "user stories"; and then asking how OOP-oriented pythonista would go-about designing a solution (classes, methods, algorithms, ...)? [which I believe is what you want to learn, under the "OOP" heading] -- Regards =dn From martin at linux-ip.net Wed Jun 10 23:07:29 2020 From: martin at linux-ip.net (Martin A. Brown) Date: Wed, 10 Jun 2020 20:07:29 -0700 Subject: [Tutor] Pythonic Style Question In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> Message-ID: Hello there, >Long time programmer (started with punch cards) but fairly new to >Python. As a kid, I played with the detritus that held leftover programs .... on punch cards. Both parents wrote in COBOL. (Imagine what data security professionals of today would say about some kid playing with the residual fragments of intellectual property.) >Decided to try running pylint on it to see what sort or 'Preferred >Style' it would lead me to (might as well have something look over >the code and critique it) (I know the weaknesses of Linters, but >worth a shot) > >Getting a lot of coding style errors for module global variables >that seem to be a reasonable way to do it, but figured I would ask >to see if there is a more Pythonic method to do these. Quite possibly! But, see below for more commentary on interpreting what you are seeing. >Example, application will have a number of settings stored in a >configuration file, so I have a myconfig.py module that is called >with the path to the config file, that uses configparser to read in >the options and create a module global variable (config) that other >parts of the system can import, and then query/set by accessing. If you show the code (or small sections), we may be able to help you find ways to avoid the warnings from globals. This is, of course, a stylistic choice that pylint is complaining about. Usually, it's possible to read the configuration data in myconfig.py and then use an import to put the name into the namespace of another problem (without making it global), and then pass it into any objects or functions which may need the configurables that came from that original configuration file. Mostly, the solution to that problem is around how to use variable scope. I'd imagine that any language you've come from probably had definitions of variable scope, so that's probably not a new idea. Here's the place in the Python docs to read about that: https://docs.python.org/3/reference/executionmodel.html#resolution-of-names Of course, it's not forbidden to use globally scoped variables, it's generally discouraged since many future sins (or bugs) can be avoided by considering scope at first-writing. I believe this would fall into the category of a "code smell" according to pylint, which is why it objects and complains. >pylint first complains that these 'constants' should be in ALL_CAPS >(but they aren't constants, so I don't think they should be >ALL_CAPS), and in the function that will set it up, complains of >the global statement so it can access the module global. I could >also create my own access wrappers to get/set options, that other >modules will call, but I would think I would still need the module >global (and making it _config to mark it as a non-global still gets >all the warnings about the constant not being ALL_CAPS). You are right about there being no 'constants' in Python (though there are some third-party libraries that try to fake that). If you don't actually need to emulate constants or provide get/set style methods, I'd say don't bother (there's a human's opinion as opposed to pylint's expression of some other humans' opinions). I.e. if you won't be offering it as a module or library to others, then, why bother with the overhead of getters and setters? >Is there another better way to do this sort of thing? or is pylint >just being over picky (as lints are prone to be) and I need to Whether the perfect critic, picky or overly picky is entirely up to you. I can tell you that when I run it on some of my sample code written to demonstrate the language I get fantastic scores. When I run it against some (reasonably well-tested) production code (which lacks the message control exemption comments), I don't get particularly good scores. Why? * Because some code has runtime characteristics that pylint cannot predict, so views with skepticism. * Because for temporary variables, I actually like one-letter characters. (o for object, d for dict, l for list, s for string) * Because (perhaps shame on me) not all of my functions have docstrings. And, some other such problems. I'm OK with not getting a particularly high score from pylint because I know why I have made most of those decisions (or the law of diminishing returns for effort have kicked in). The pylint manual introduction is reasonably self-aware about this, too, which is nice. It's a good tool (and actually, running it just now on some production code, I see some things that I might go back and revisit): https://pylint.readthedocs.io/en/latest/intro.html > .. put a comment on the statement to tell pylint it is ok? Yes, you certainly can: https://pylint.readthedocs.io/en/latest/user_guide/message-control.html You can try it out by running: pylint -d line-too-long,invalid-name ./path/to/your/proggie.py I haven't tried "# pylint: disable=line-too-long,invalid-name" because I kind of like seeing the grousing, in the cases that I run pylint. On the other hand, I do have some minimal expectations. While I rarely use pylint, but I hew (generally) to pyflakes and pep8, so I run the following as a part of continuous integration / or VCS hooks: flake8 --ignore E501 And, I ignore that one because, as a verbose lout, I sometimes end up with lines longer than 80 characters. -Martin -- Martin A. Brown http://linux-ip.net/ From alan.gauld at yahoo.co.uk Thu Jun 11 05:00:33 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 11 Jun 2020 10:00:33 +0100 Subject: [Tutor] Can anyone help answer this? In-Reply-To: References: Message-ID: On 10/06/2020 15:31, Peter Otten wrote: >> And the Pythonic way of building lists is a list comprehension. >> So this whole exercise should be reduced to: >> >> food_list = [Food(t) for t in tuple_list] > > You forgot the * which I think is an advanced and even somewhat questionable > feature. You are right, but its not needed here. We could still use a comprehension with: food_list = [Food(name,taste) for name,taste in tuple_list] utilising tuple unpacking. > which gives opportunities to show > > - idiomatic iteration > - tuple unpacking > - good ways for a function to communicate with its caller. > > You may argue that this should have been taught before starting with custom > objects... Yes, that was my point. The exercise appears to be all about instantiating objects, but then misses the whole point of having objects in the first place - that the functionality resides inside the object. Encouraging students to create functions that just use the constructor to return a list is bad practice and also teaching a bad way of thinking. It is exactly this kind of teaching that results in the poor understanding of OOP that we see so often today. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Thu Jun 11 06:28:22 2020 From: __peter__ at web.de (Peter Otten) Date: Thu, 11 Jun 2020 12:28:22 +0200 Subject: [Tutor] Pythonic Style Question References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> Message-ID: Richard Damon wrote: > Background: > > Long time programmer (started with punch cards) but fairly new to punch > cards, but fairly new to Python. > > Working on a program that will be a moderate size program when done, and > doing it in Python as it looks to be a reasonable choice, and a good > learning experience. > > Decided to try running pylint on it to see what sort or 'Preferred > Style' it would lead me to (might as well have something look over the > code and critique it) (I know the weaknesses of Linters, but worth a shot) > > Getting a lot of coding style errors for module global variables that > seem to be a reasonable way to do it, but figured I would ask to see if > there is a more Pythonic method to do these. > > Example, application will have a number of settings stored in a > configuration file, so I have a myconfig.py module that is called with > the path to the config file, that uses configparser to read in the > options and create a module global variable (config) that other parts of > the system can import, and then query/set by accessing. Do you use the global statement to rebind the global `config` name def read_config() global config config = ... read_config() or to modify it def update_config(): global config config.working_directory = ... ? In the second example `global` is unnecessary, in the first you might at least consider changing it to def read_config(): config = ... return config config = read_config() > pylint first complains that these 'constants' should be in ALL_CAPS (but > they aren't constants, so I don't think they should be ALL_CAPS), I think that's indeed very annoying. I sometimes ignore it and sometimes tinker with the config file's const-rgx. If I understand http://pylint.pycqa.org/en/latest/whatsnew/2.5.html correctly the situation may have improved. > and in > the function that will set it up, complains of the global statement so > it can access the module global. I could also create my own access > wrappers to get/set options, that other modules will call, but I would > think I would still need the module global (and making it _config to > mark it as a non-global still gets all the warnings about the constant > not being ALL_CAPS). > > Is there another better way to do this sort of thing? or is pylint just > being over picky (as lints are prone to be) and I need to put a comment > on the statement to tell pylint it is ok? Having as few global variables as possible (but not fewer) seems a good idea to me. From alan.gauld at yahoo.co.uk Thu Jun 11 06:45:40 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 11 Jun 2020 11:45:40 +0100 Subject: [Tutor] Pythonic Style Question In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> Message-ID: On 11/06/2020 03:03, Richard Damon wrote: > Long time programmer (started with punch cards) You are not alone on this list, although in my case it was paper tape... > Getting a lot of coding style errors for module global variables that > seem to be a reasonable way to do it, but figured I would ask to see if > there is a more Pythonic method to do these. As an experienced programmer i'm sure you know why globals are generally frowned on and the usual techniques for getting rid of them (pass as function parameters return as values etc.) > Example, application will have a number of settings stored in a > configuration file, so I have a myconfig.py module that is called with > the path to the config file, that uses configparser to read in the > options and create a module global variable (config) that other parts of > the system can import, and then query/set by accessing. A lot depends on what kind of data you are storing but one common trick for dealing with shared constants etc is to put them in a python module and then import that module into every other module that requires access. You can then edit the python module when you want to modify the settings. ######## my_globals.py ##### SIZE = 42 SCALE = 66 label = "My funky app" ############################# ##### Myapp.py ##### import my_globals as globals print (The size is: ", globals.SIZE) globals.label = input("What label do you want? ") etc... Not sure if that helps at all but its something that non-python programmers often overlook as a possibility. Obviously there are security/reliability issues in allowing users to modify the code, but thats true any time you ship source. If its on a server or other secured location or its for your own use then it should be OK. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From Richard at Damon-Family.org Thu Jun 11 07:19:55 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 11 Jun 2020 07:19:55 -0400 Subject: [Tutor] Pythonic Style Question In-Reply-To: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> References: <1ae87c75-c05f-5e4a-6a6a-c7948da25e0b@Damon-Family.org> Message-ID: <6f40e4e8-1edb-01f1-2478-66109bb5301c@Damon-Family.org> On 6/10/20 10:03 PM, Richard Damon wrote: > Background: > > Long time programmer (started with punch cards) but fairly new to punch > cards, but fairly new to Python. > > Working on a program that will be a moderate size program when done, and > doing it in Python as it looks to be a reasonable choice, and a good > learning experience. > > Decided to try running pylint on it to see what sort or 'Preferred > Style' it would lead me to (might as well have something look over the > code and critique it) (I know the weaknesses of Linters, but worth a shot) > > Getting a lot of coding style errors for module global variables that > seem to be a reasonable way to do it, but figured I would ask to see if > there is a more Pythonic method to do these. > > Example, application will have a number of settings stored in a > configuration file, so I have a myconfig.py module that is called with > the path to the config file, that uses configparser to read in the > options and create a module global variable (config) that other parts of > the system can import, and then query/set by accessing. > > pylint first complains that these 'constants' should be in ALL_CAPS (but > they aren't constants, so I don't think they should be ALL_CAPS), and in > the function that will set it up, complains of the global statement so > it can access the module global. I could also create my own access > wrappers to get/set options, that other modules will call, but I would > think I would still need the module global (and making it _config to > mark it as a non-global still gets all the warnings about the constant > not being ALL_CAPS). > > Is there another better way to do this sort of thing? or is pylint just > being over picky (as lints are prone to be) and I need to put a comment > on the statement to tell pylint it is ok? > For the question of sample code, showing what I am doing myconfig.py import configparser # Path to the currently used config file config_path = None # Contents of the currently used configuration config = None def load_configuration(path): ??? """ Load the Configuration file """ ??? global config_path ??? config_path = path ??? global config ??? config = configparser.ConfigParser() ??? config.read(path) ??? # Add Sections we will use if not present ??? if 'General' not in config.sections(): ??????? config['General'] = {} ??? if 'Default' not in config.sections(): ??????? config['Defaults'] = {} ??? if 'Recent' not in config.sections(): ??????? config['Recent'] = {} ?? # other defaults added here ?? save_configuration() def save_configuration(): ??? """ Save the current configuration""" ??? with open(config_path, 'w') as configfile: ??????? config.write(configfile) Now, config_path probably should be _config_path as other modules shouldn't be using it. But many modules will be doing something like import myconfig # ??? data_dir = myconfig.config['General']['DataDirectory'] To get the directory which the user has specified to put the various data files for the program. Yes, lots of globals are a sign of a problem, but this sort of config data has bits for lots of parts of the program, and making each part read its own data sounds worse, and just pushes down to problem as then the name of the config file needs to be global, as it can be overridden at program startup. I suppose I could get rid of the global config statement by initializing config to the configparser at the global level, but the None initialization will create an error if I try to use the config information before I call myconfig.load_configuration(). I am using a recent version (2.5.2) but maybe the None initialization is what is making it think it is a constant. Initializing it to the ConfigParser at global scope does make it no longer get flagged as constant Now, the final answer is probably adding the #pylint comments around the sections containing the unrecognized module globals, and treat them as the mark that I have made the deliberate decision to 'bend the rules' (at least as interpreted by pylint). -- Richard Damon From john at johnweller.co.uk Fri Jun 12 13:59:16 2020 From: john at johnweller.co.uk (John Weller) Date: Fri, 12 Jun 2020 18:59:16 +0100 Subject: [Tutor] Reading a CSV file Message-ID: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> I have a CSV file with 366 rows each with 4 comma separated fields; day_no, date, sunrise, sunset. The top row contains the field names. I want access the time of sunrise and sunset from file for a particular day_no. I have tried: import csv with open('sun_times_gmt.csv', newline= '') as csvfile: sun_times = csv.DictReader(csvfile, delimiter=',') for row in sun_times: print(row['sunrise']) but it prints out the entire column. How do I specify a particular row? TIA John Weller 01380 723235 07976 393631 From david at graniteweb.com Fri Jun 12 18:42:57 2020 From: david at graniteweb.com (David Rock) Date: Fri, 12 Jun 2020 17:42:57 -0500 Subject: [Tutor] Reading a CSV file In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> Message-ID: <20200612224257.GX27796@apple.graniteweb.com> * John Weller [2020-06-12 18:59]: > I have a CSV file with 366 rows each with 4 comma separated fields; day_no, > date, sunrise, sunset. The top row contains the field names. I want access > the time of sunrise and sunset from file for a particular day_no. > > > > I have tried: > > > > import csv > > with open('sun_times_gmt.csv', newline= '') as csvfile: > sun_times = csv.DictReader(csvfile, delimiter=',') > for row in sun_times: > print(row['sunrise']) > > > but it prints out the entire column. How do I specify a particular row? This is because you are telling it to print every row. You need to add an if statement that prints only if day_no matches the entry you want. For example: with open('sun_times_gmt.csv', newline= '') as csvfile: sun_times = csv.DictReader(csvfile, delimiter=',') for row in sun_times: if row['day_no'] == 'your day_no value here': print(row['sunrise']) You could also play around with using the value of day_no to be a key for the data so you can access it more directly. If day_no is unique, you can do this: days = {} with open('sun_times_gmt.csv', newline= '') as csvfile: sun_times = csv.DictReader(csvfile, delimiter=',') for row in sun_times: days[row['day_no']] = row print(days['your day_no value here']['sunrise']) It depends on exactly how you want to reference the data later -- David Rock david at graniteweb.com From cs at cskk.id.au Fri Jun 12 18:46:38 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 13 Jun 2020 08:46:38 +1000 Subject: [Tutor] Reading a CSV file In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> Message-ID: <20200612224638.GA98411@cskk.homeip.net> On 12Jun2020 18:59, John Weller wrote: >I have a CSV file with 366 rows each with 4 comma separated fields; day_no, >date, sunrise, sunset. The top row contains the field names. I want access >the time of sunrise and sunset from file for a particular day_no. > >I have tried: > >import csv > >with open('sun_times_gmt.csv', newline= '') as csvfile: > sun_times = csv.DictReader(csvfile, delimiter=',') > for row in sun_times: > print(row['sunrise']) > >but it prints out the entire column. How do I specify a particular >row? By putting the print inside an if-statement that recognises the row. So changing: for row in sun_times: print(row['sunrise']) into: for row in sun_times: if some test of row['day_no']: print(row['sunrise']) which will cause the print statement to only work if the test succeeds. What the test is depends on what "a particular day_no" means. Cheers, Cameron Simpson From alexkleider at protonmail.com Fri Jun 12 21:30:22 2020 From: alexkleider at protonmail.com (alexkleider) Date: Sat, 13 Jun 2020 01:30:22 +0000 Subject: [Tutor] Reading a CSV file In-Reply-To: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> Message-ID: ??????? Original Message ??????? On Friday, June 12, 2020 10:59 AM, John Weller wrote: > I have a CSV file with 366 rows each with 4 comma separated fields; day_no, > date, sunrise, sunset. The top row contains the field names. I want access > the time of sunrise and sunset from file for a particular day_no. > I have tried: > import csv > with open('sun_times_gmt.csv', newline= '') as csvfile: > sun_times = csv.DictReader(csvfile, delimiter=',') > for row in sun_times: > print(row['sunrise']) > but it prints out the entire column. How do I specify a particular row? > TIA > John Weller Try adding an if statements as follows: for row in sun_times: if row['day_no'] == my_day_number: print(row['sunrise']) From david at graniteweb.com Sat Jun 13 12:18:18 2020 From: david at graniteweb.com (David Rock) Date: Sat, 13 Jun 2020 11:18:18 -0500 Subject: [Tutor] Reading a CSV file In-Reply-To: <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk> References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> <20200612224257.GX27796@apple.graniteweb.com> <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk> Message-ID: <20200613161818.GG27796@apple.graniteweb.com> * John Weller [2020-06-13 15:59]: > Many thanks to all who replied. I hoped it would be something like a > dictionary. The docs say that a dictionary is a sequence of key pairs - > key:value but it appears that the value can be several fields. Is this the > case? No. Dictionaries are key:value pairs, but "value" can be any type of object. For example, the "value" could be another dictionary, a list, etc; all of which have the potential to hold multiple items, not just a single value. > This program is intended to run 24/7 getting data every 10 minutes and using > it to control equipment dependent on whether it is day or night. There will > be a setup function and a loop function. I assume I can put the first part > to create the dictionary is setup and the call in the loop? Yes, that's exactly how my example is being used in stuff I'm doing. Load the data into a dictionary once and reference it later. It's a lot faster than repeatedly walking the file. The only reason to do that would be if the data you are reading from changes every time. If it's a static table, read it once and reference the dictionary instead. Another thing you my find handy is the pretty print module (pprint). As a test, after you create your sun_times OrderedDict with the csv module, try doing: pprint.pprint(sun_times) to get a solid understanding of the layout of the dictionary created by the csv module. -- David Rock david at graniteweb.com From 1611kjb at gmail.com Sat Jun 13 12:27:49 2020 From: 1611kjb at gmail.com (Michael Deslippe) Date: Sat, 13 Jun 2020 16:27:49 +0000 Subject: [Tutor] Inclusivity Message-ID: When generating a random integer, ala; myNum = random.randint(0, 1000000) Is the range of integers inclusive or exclusive of the seed values (eg. will the range of possible answers include or exclude 0 and 1000000)? ---Mike From john at johnweller.co.uk Sat Jun 13 10:59:23 2020 From: john at johnweller.co.uk (John Weller) Date: Sat, 13 Jun 2020 15:59:23 +0100 Subject: [Tutor] Reading a CSV file In-Reply-To: <20200612224257.GX27796@apple.graniteweb.com> References: <003701d640e3$3136d800$93a48800$@johnweller.co.uk> <20200612224257.GX27796@apple.graniteweb.com> Message-ID: <008f01d64193$3bbb0ac0$b3312040$@johnweller.co.uk> Many thanks to all who replied. I hoped it would be something like a dictionary. The docs say that a dictionary is a sequence of key pairs - key:value but it appears that the value can be several fields. Is this the case? This program is intended to run 24/7 getting data every 10 minutes and using it to control equipment dependent on whether it is day or night. There will be a setup function and a loop function. I assume I can put the first part to create the dictionary is setup and the call in the loop? Thanks again John John Weller 01380 723235 07976 393631 -----Original Message----- From: Tutor On Behalf Of David Rock Sent: 12 June 2020 23:43 To: tutor at python.org Subject: Re: [Tutor] Reading a CSV file * John Weller [2020-06-12 18:59]: > I have a CSV file with 366 rows each with 4 comma separated fields; > day_no, date, sunrise, sunset. The top row contains the field names. > I want access the time of sunrise and sunset from file for a particular day_no. > > > > I have tried: > > > > import csv > > with open('sun_times_gmt.csv', newline= '') as csvfile: > sun_times = csv.DictReader(csvfile, delimiter=',') > for row in sun_times: > print(row['sunrise']) > > > but it prints out the entire column. How do I specify a particular row? This is because you are telling it to print every row. You need to add an if statement that prints only if day_no matches the entry you want. For example: with open('sun_times_gmt.csv', newline= '') as csvfile: sun_times = csv.DictReader(csvfile, delimiter=',') for row in sun_times: if row['day_no'] == 'your day_no value here': print(row['sunrise']) You could also play around with using the value of day_no to be a key for the data so you can access it more directly. If day_no is unique, you can do this: days = {} with open('sun_times_gmt.csv', newline= '') as csvfile: sun_times = csv.DictReader(csvfile, delimiter=',') for row in sun_times: days[row['day_no']] = row print(days['your day_no value here']['sunrise']) It depends on exactly how you want to reference the data later -- David Rock david at graniteweb.com _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From swetha-m at lntnxt.com Sat Jun 13 16:02:21 2020 From: swetha-m at lntnxt.com (Swetha M) Date: Sat, 13 Jun 2020 20:02:21 +0000 Subject: [Tutor] Tensorflow Installation in Python Embedded Environment Message-ID: Hi, I recently came across an issue while installing tensorflow library on Python Embedded environment(64-bit). During installation, there was a library - 'termcolor' which showed up as error saying, module does not exist. Then I tried installing only termcolor library thinking there can be version issue with tensorflow package. Same Error came up. Since it used a cached version I thought there was a compatibility contradiction with the python environment in my system. I tried all means to remove cached version, didn't work. And I had anaconda running, so I thought there was some environment path clash and stuff while trying to download from http. I opened another command prompt, installed termcolor in the python environment of me system and it was installed successfully. Then in the previous command prompt where installation of termcolor was failing, I tried the same command and it was installed without any errors. Then I installed tensorflow and it was installed successfully too. Although I was able to install, I would really like to know the root cause of this issue. I have attached some screenshots for reference. I would really appreciate any help on this particular issue. Just for your notice, same scenario experienced in lower versions of python embedded too. (3.7) Also, I have a few general queries: Are there any differences at all between python installed in the system and using embedded package? Can I use heavy libraries like tensorflow in the embedded environment? Are there any performance related differences between those two methods? Any help on these queries would be very helpful. Thank You, Regards, Swetha M Larsen & Toubro Limited www.larsentoubro.com This Email may contain confidential or privileged information for the intended recipient (s). If you are not the intended recipient, please do not use or disseminate the information, notify the sender and delete it from your system. From alan.gauld at yahoo.co.uk Sat Jun 13 18:44:27 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 13 Jun 2020 23:44:27 +0100 Subject: [Tutor] Inclusivity In-Reply-To: References: Message-ID: On 13/06/2020 17:27, Michael Deslippe wrote: > When generating a random integer, ala; > > myNum = random.randint(0, 1000000) > > Is the range of integers inclusive or exclusive of the seed values When in doubt use the tools: ############################# Help on method randint in module random: randint(self, a, b) method of random.Random instance Return random integer in range [a, b], including both end points. (END) ########################### -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From bouncingcats at gmail.com Sat Jun 13 20:29:20 2020 From: bouncingcats at gmail.com (David) Date: Sun, 14 Jun 2020 10:29:20 +1000 Subject: [Tutor] Inclusivity In-Reply-To: References: Message-ID: On Sun, 14 Jun 2020 at 08:43, Michael Deslippe <1611kjb at gmail.com> wrote: > When generating a random integer, ala; > myNum = random.randint(0, 1000000) > Is the range of integers inclusive or exclusive of the seed values (eg. will the range of possible answers include or exclude 0 and 1000000)? $ python3 Python 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import random >>> help(random.randint) Help on method randint in module random: randint(a, b) method of random.Random instance Return random integer in range [a, b], including both end points. >>> From krishp52 at rocketmail.com Sun Jun 14 08:09:30 2020 From: krishp52 at rocketmail.com (Krish P) Date: Sun, 14 Jun 2020 12:09:30 +0000 (UTC) Subject: [Tutor] python References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> Message-ID: <1218488951.459090.1592136570249@mail.yahoo.com> The Syracuse (also called the Collatz Hailstone) sequence is generated by starting with anatural number and repeatedly applying the following function:???(?) = ??/2, ?? ? ?? ????3? + 1, ?? ? ?? ???For example the Syracuse sequence starting with number 5 is: 5,16,8,4,2,1. This is an openquestion in mathematics whether this sequence will always go to 1 for every possible startingvalue. Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications called ?data.txt?.This data file contains natural numbers, one on each line.1. Your role as a programmer is to create a program that will read all this data from the fileand generate the Syracuse sequence for each of those numbers.2. Additionally, you have to write every one of these Syracuse sequences into a file calledSyra.txt using your code. data.txt:5171489041560302625118640372871807577663267444425332206991424075339339242048076287520376042156789972989546896669773172194641692345396892524370564098552375921179116691885394649252421723842536911736 From alan.gauld at yahoo.co.uk Sun Jun 14 13:43:56 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 14 Jun 2020 18:43:56 +0100 Subject: [Tutor] python In-Reply-To: <1218488951.459090.1592136570249@mail.yahoo.com> References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> <1218488951.459090.1592136570249@mail.yahoo.com> Message-ID: On 14/06/2020 13:09, Krish P via Tutor wrote: > ...your assignment specifications ...to create a program that will read all this data > from the file and generate the Syracuse sequence for each > 2. Additionally, you have to write every one of these Syracuse sequence> into a file calledSyra.txt using your code. It looks like you got a reasonable description of the problem to be solved. How did you get on? Got any code yet? Does it work? If so, well done! If not, how would you like us to help? What error messages do you get? How close is the data out to what you expected? What aspects of the assignment do you not understand? Which OS are you using? Which python version? Do you have programming experience in other languages? Or are you a beginner? The more you help us the more we can help you. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PyTutor at danceswithmice.info Sun Jun 14 16:49:41 2020 From: PyTutor at danceswithmice.info (DL Neil) Date: Mon, 15 Jun 2020 08:49:41 +1200 Subject: [Tutor] python In-Reply-To: <1218488951.459090.1592136570249@mail.yahoo.com> References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> <1218488951.459090.1592136570249@mail.yahoo.com> Message-ID: <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info> On 15/06/20 12:09 AM, Krish P via Tutor wrote: > The Syracuse (also called the Collatz Hailstone) sequence... > Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications... In case you have not met "Moodle" before, it is an LMS (Learning Management System). It can be thought-of as a Content Management System with add-ons specifically designed for training, eg presenting lectures and papers, references, quizzes and exams, and so-forth. Think of it as the on-line equivalent of the binders of 'stuff' we used to accumulate as the academic year progressed (or the teacher's equivalent thereof). Something else, of which you may be unaware: Another characteristic of today's education is that as well as the on-line teaching materials, there are also 'services', often known as "paper mills" or "term paper writing services", which offer to complete academic works - in exchange for money. Surprise, shock, horror! Thus, plagiarism and other enablers of 'cognitive by-pass learning' have exploded into a massive problem and dilute the value of certifications and degrees. The OP was brutally honest that this is an academic assignment, even if what was being asked of us was unclear! I wouldn't like to suggest that the OP thought us a 'paper mill' for ComSc, but the post is exactly how one might present to such. (the expected response being a $quotation for the work) All of which may help to explain (if you are sometimes mystified by an apparent, and yet uncharacteristic, lack of 'helpfulness') why some of us *deliberately* avoid giving a direct answer to some posts. Instead, we will point to references where learning should take-place - and thus the *actual objective* be achieved. ("Socratic approach", 'engendering curiosity', blah, blah, psychology...) -- Regards =dn From alan.gauld at yahoo.co.uk Sun Jun 14 19:29:36 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 15 Jun 2020 00:29:36 +0100 Subject: [Tutor] python In-Reply-To: <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info> References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> <1218488951.459090.1592136570249@mail.yahoo.com> <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info> Message-ID: On 14/06/2020 21:49, DL Neil via Tutor wrote: > there are also 'services', often known as "paper mills" or "term paper > writing services", which offer to complete academic works - in exchange > for money. I can't pretend to begin to understand the rationale for using such a service. Does such a student expect to get a job after qualifying? If they can't even do the near trivial assignments given out in school/college how do they expect to do a job in the real world with real problems? Such a service would never have succeeded in my time at school, students were in perpetual penury and could never afford to employ such a thing! Of course that was before "student loans" became a thing... :-/ -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From oscar.j.benjamin at gmail.com Sun Jun 14 20:09:04 2020 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 15 Jun 2020 01:09:04 +0100 Subject: [Tutor] python In-Reply-To: References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> <1218488951.459090.1592136570249@mail.yahoo.com> <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info> Message-ID: On Mon, 15 Jun 2020 at 00:30, Alan Gauld via Tutor wrote: > > On 14/06/2020 21:49, DL Neil via Tutor wrote: > > there are also 'services', often known as "paper mills" or "term paper > > writing services", which offer to complete academic works - in exchange > > for money. > > I can't pretend to begin to understand the rationale for > using such a service. Speaking as someone who teaches introductory programming to undergraduate Engineering students I've seen this happen and in my experience it comes more from desperation then calm rational thinking. > Does such a student expect to get a job after qualifying? If they > can't even do the near trivial assignments given out in > school/college how do they expect to do a job in the real > world with real problems? Our students after graduating (as Engineers) will go on to do many different things. Some of them will become professional programmers and many more will be able to make use of their programming skills but most will not really do any programming after graduating. We hope they learned something from the experience of programming even if it doesn't become a core part of their future career. I can see though that some students think that programming units are just a hoop that they might successfully go round rather than jump through. > Such a service would never have succeeded in my time at school, > students were in perpetual penury and could never afford to > employ such a thing! Of course that was before "student loans" > became a thing... :-/ There is significant variability in the wealth of students. There are plenty enough who can afford to pay for these kinds of services that it is clearly a viable business for those offering the services. Whether it's viable for the customers is a different question: generally the cases I know of do not lead ultimately to academic success (i.e. graduation). Unfortunately I can't speak for the cases I *don't* know of... -- Oscar From PyTutor at danceswithmice.info Sun Jun 14 20:11:37 2020 From: PyTutor at danceswithmice.info (dn) Date: Mon, 15 Jun 2020 12:11:37 +1200 Subject: [Tutor] python In-Reply-To: References: <1218488951.459090.1592136570249.ref@mail.yahoo.com> <1218488951.459090.1592136570249@mail.yahoo.com> <2b2ed393-7001-1e06-0106-5860bca574f9@DancesWithMice.info> Message-ID: <453d29e7-2036-c419-4558-41929363d390@DancesWithMice.info> On 15/06/20 11:29 AM, Alan Gauld via Tutor wrote: > On 14/06/2020 21:49, DL Neil via Tutor wrote: >> there are also 'services', often known as "paper mills" or "term paper >> writing services", which offer to complete academic works - in exchange >> for money. > > I can't pretend to begin to understand the rationale for > using such a service. > > Does such a student expect to get a job after qualifying? If they > can't even do the near trivial assignments given out in > school/college how do they expect to do a job in the real > world with real problems? > > Such a service would never have succeeded in my time at school, > students were in perpetual penury and could never afford to > employ such a thing! Of course that was before "student loans" > became a thing... :-/ The rationale is actually quite evident: when one arrives at university (or...), it doesn't take long to discover that there are some (other) extremely intelligent folk who might well be 'better' than you are. Plus, there are the usual 'pressures' of "time" and total-disasters when it comes to the skill of making the best use of one's time. Another is 'competition' and the pressures of "continuous assessment" (numbers of tests/contributors to the final grade throughout the course) cf the once-uniform 'it all comes down to the final-exam' course-approach. Accordingly, one can't have 'an off-day' because every piece of work 'counts'. (sort of like paid-employment then!) Accordingly, the temptation of finding any 'short-cut'. You have touched-upon one of the reasons why I prefer the (old) technical institute/polytechnic/community college approach to *training* as opposed to the university approach to *education*. (if you don't understand the significance or subtlety of this comment, prepend "sex" to those two words and consider if they are 'the same'!) Unlike yourself, I do not teach/train Python, but do other languages and tech-skills. We both want to see employable 'graduates', either as trainer or as employer. What we are seeking is "Mastery". Can the person (now) *do* the job/task/write the program(me)? Do, or die! Does a student, faced with a likely 'fail' think about his/her future employment - or is (s)he all-consumed by securing a (good) pass for the current assignment? Don't get me started on the economic fallacies of 'student loans'! You must have been 'a good, little, boy'. Such services were very much available (in a different form) when we were at-school (walking miles each-way, no shoes, knee-high snow, fearful of attacks by dinosaurs...). There were always seniors/post-grads, etc, who were keen to 'make a quid/buck'. However, their lives were very much more risky because the institution could easily detect what was a-foot AND could reach-out and grab the miscreants for suitable punishment. These days, the student and 'ghost-writer' could be continents apart - and far from the reach of 'justice'! My first job at the university was as a marker (grader, these days perhaps "teaching assistant"). After a date-due, I would receive hundreds of multi-page printouts of COBOL or FORTRAN, and results. (could fill a small suit-case!) A few days later, I would return to the lecturer and drop multiple distinct piles on his desk. The 'good pile' was the distinct and passing efforts. The 'bad pile' was distinct but failing results. The other piles were all 'copies' - each member of the pile (and there were often dozens) were essentially identical - but the different piles of 'copies' were differently characteristic. I was always grateful that I didn't have to (a) identify who was the original author whose work passed/failed, or (b) decide how to mark (grade) or punish such. He repeatedly gave me 'glowing recommendations' because of the revelation of my ability to 'see' such patterns (which habit one would expect from systems analysts and designers, so shouldn't be 'that' special!). So, "nothing new under the sun" then! -- Regards =dn From jtarun960 at gmail.com Sun Jun 14 23:01:02 2020 From: jtarun960 at gmail.com (Chirag Jain) Date: Mon, 15 Jun 2020 08:31:02 +0530 Subject: [Tutor] i want a solution to my problem Message-ID: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> module 'sqlite300.sqlite3' has no attribute 'connect' I m getting this error even if I had changed the name of the file what should I do to overcome this problem. Thank you Sent from Mail for Windows 10 From krishp52 at rocketmail.com Sun Jun 14 21:34:31 2020 From: krishp52 at rocketmail.com (Krish P) Date: Mon, 15 Jun 2020 01:34:31 +0000 (UTC) Subject: [Tutor] Tutor Digest, Vol 196, Issue 28 In-Reply-To: References: Message-ID: <729354972.640706.1592184871457@mail.yahoo.com> Hi, thanks for your response. I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file. given is the code that I came up with: def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB ? ? f = open("data.txt", "r")? ? print(f.read()) ? ??main() Waiting for your kind assistanceThanksKrish On Monday, June 15, 2020, 12:13:14 PM GMT+12, wrote: Send Tutor mailing list submissions to ??? tutor at python.org To subscribe or unsubscribe via the World Wide Web, visit ??? https://mail.python.org/mailman/listinfo/tutor or, via email, send a message with subject or body 'help' to ??? tutor-request at python.org You can reach the person managing the list at ??? tutor-owner at python.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Tutor digest..." Today's Topics: ? 1. Re: python (Alan Gauld) ? 2. Re: python (DL Neil) ? 3. Re: python (Alan Gauld) ? 4. Re: python (Oscar Benjamin) ? 5. Re: python (dn) ---------------------------------------------------------------------- Message: 1 Date: Sun, 14 Jun 2020 18:43:56 +0100 From: Alan Gauld To: tutor at python.org Subject: Re: [Tutor] python Message-ID: Content-Type: text/plain; charset=utf-8 On 14/06/2020 13:09, Krish P via Tutor wrote: > ...your assignment specifications ...to create a program that will read all this data > from the file and generate the Syracuse sequence for each > 2. Additionally, you have to write every one of these Syracuse sequence> into a file calledSyra.txt using your code. It looks like you got a reasonable description of the problem to be solved. How did you get on? Got any code yet? Does it work? If so, well done! If not, how would you like us to help? What error messages do you get? How close is the data out to what you expected? What aspects of the assignment do you not understand? Which OS are you using? Which python version? Do you have programming experience in other languages? Or are you a beginner? The more you help us the more we can help you. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ------------------------------ Message: 2 Date: Mon, 15 Jun 2020 08:49:41 +1200 From: DL Neil To: tutor at python.org Subject: Re: [Tutor] python Message-ID: <2b2ed393-7001-1e06-0106-5860bca574f9 at DancesWithMice.info> Content-Type: text/plain; charset=utf-8; format=flowed On 15/06/20 12:09 AM, Krish P via Tutor wrote: > The Syracuse (also called the Collatz Hailstone) sequence... > Problem to be SolvedYou will find a data file on Moodle alongside your assignment specifications... In case you have not met "Moodle" before, it is an LMS (Learning Management System). It can be thought-of as a Content Management System with add-ons specifically designed for training, eg presenting lectures and papers, references, quizzes and exams, and so-forth. Think of it as the on-line equivalent of the binders of 'stuff' we used to accumulate as the academic year progressed (or the teacher's equivalent thereof). Something else, of which you may be unaware: Another characteristic of today's education is that as well as the on-line teaching materials, there are also 'services', often known as "paper mills" or "term paper writing services", which offer to complete academic works - in exchange for money. Surprise, shock, horror! Thus, plagiarism and other enablers of 'cognitive by-pass learning' have exploded into a massive problem and dilute the value of certifications and degrees. The OP was brutally honest that this is an academic assignment, even if what was being asked of us was unclear! I wouldn't like to suggest that the OP thought us a 'paper mill' for ComSc, but the post is exactly how one might present to such. (the expected response being a $quotation for the work) All of which may help to explain (if you are sometimes mystified by an apparent, and yet uncharacteristic, lack of 'helpfulness') why some of us *deliberately* avoid giving a direct answer to some posts. Instead, we will point to references where learning should take-place - and thus the *actual objective* be achieved. ("Socratic approach", 'engendering curiosity', blah, blah, psychology...) -- Regards =dn ------------------------------ Message: 3 Date: Mon, 15 Jun 2020 00:29:36 +0100 From: Alan Gauld To: tutor at python.org Subject: Re: [Tutor] python Message-ID: Content-Type: text/plain; charset=utf-8 On 14/06/2020 21:49, DL Neil via Tutor wrote: > there are also 'services', often known as "paper mills" or "term paper > writing services", which offer to complete academic works - in exchange > for money. I can't pretend to begin to understand the rationale for using such a service. Does such a student expect to get a job after qualifying? If they can't even do the near trivial assignments given out in school/college how do they expect to do a job in the real world with real problems? Such a service would never have succeeded in my time at school, students were in perpetual penury and could never afford to employ such a thing! Of course that was before "student loans" became a thing... :-/ -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ------------------------------ Message: 4 Date: Mon, 15 Jun 2020 01:09:04 +0100 From: Oscar Benjamin To: Alan Gauld Cc: tutor Subject: Re: [Tutor] python Message-ID: ??? Content-Type: text/plain; charset="UTF-8" On Mon, 15 Jun 2020 at 00:30, Alan Gauld via Tutor wrote: > > On 14/06/2020 21:49, DL Neil via Tutor wrote: > > there are also 'services', often known as "paper mills" or "term paper > > writing services", which offer to complete academic works - in exchange > > for money. > > I can't pretend to begin to understand the rationale for > using such a service. Speaking as someone who teaches introductory programming to undergraduate Engineering students I've seen this happen and in my experience it comes more from desperation then calm rational thinking. > Does such a student expect to get a job after qualifying? If they > can't even do the near trivial assignments given out in > school/college how do they expect to do a job in the real > world with real problems? Our students after graduating (as Engineers) will go on to do many different things. Some of them will become professional programmers and many more will be able to make use of their programming skills but most will not really do any programming after graduating. We hope they learned something from the experience of programming even if it doesn't become a core part of their future career. I can see though that some students think that programming units are just a hoop that they might successfully go round rather than jump through. > Such a service would never have succeeded in my time at school, > students were in perpetual penury and could never afford to > employ such a thing! Of course that was before "student loans" > became a thing... :-/ There is significant variability in the wealth of students. There are plenty enough who can afford to pay for these kinds of services that it is clearly a viable business for those offering the services. Whether it's viable for the customers is a different question: generally the cases I know of do not lead ultimately to academic success (i.e. graduation). Unfortunately I can't speak for the cases I *don't* know of... -- Oscar ------------------------------ Message: 5 Date: Mon, 15 Jun 2020 12:11:37 +1200 From: dn To: tutor at python.org Subject: Re: [Tutor] python Message-ID: <453d29e7-2036-c419-4558-41929363d390 at DancesWithMice.info> Content-Type: text/plain; charset=utf-8; format=flowed On 15/06/20 11:29 AM, Alan Gauld via Tutor wrote: > On 14/06/2020 21:49, DL Neil via Tutor wrote: >> there are also 'services', often known as "paper mills" or "term paper >> writing services", which offer to complete academic works - in exchange >> for money. > > I can't pretend to begin to understand the rationale for > using such a service. > > Does such a student expect to get a job after qualifying? If they > can't even do the near trivial assignments given out in > school/college how do they expect to do a job in the real > world with real problems? > > Such a service would never have succeeded in my time at school, > students were in perpetual penury and could never afford to > employ such a thing! Of course that was before "student loans" > became a thing... :-/ The rationale is actually quite evident: when one arrives at university (or...), it doesn't take long to discover that there are some (other) extremely intelligent folk who might well be 'better' than you are. Plus, there are the usual 'pressures' of "time" and total-disasters when it comes to the skill of making the best use of one's time. Another is 'competition' and the pressures of "continuous assessment" (numbers of tests/contributors to the final grade throughout the course) cf the once-uniform 'it all comes down to the final-exam' course-approach. Accordingly, one can't have 'an off-day' because every piece of work 'counts'. (sort of like paid-employment then!) Accordingly, the temptation of finding any 'short-cut'. You have touched-upon one of the reasons why I prefer the (old) technical institute/polytechnic/community college approach to *training* as opposed to the university approach to *education*. (if you don't understand the significance or subtlety of this comment, prepend "sex" to those two words and consider if they are 'the same'!) Unlike yourself, I do not teach/train Python, but do other languages and tech-skills. We both want to see employable 'graduates', either as trainer or as employer. What we are seeking is "Mastery". Can the person (now) *do* the job/task/write the program(me)? Do, or die! Does a student, faced with a likely 'fail' think about his/her future employment - or is (s)he all-consumed by securing a (good) pass for the current assignment? Don't get me started on the economic fallacies of 'student loans'! You must have been 'a good, little, boy'. Such services were very much available (in a different form) when we were at-school (walking miles each-way, no shoes, knee-high snow, fearful of attacks by dinosaurs...). There were always seniors/post-grads, etc, who were keen to 'make a quid/buck'. However, their lives were very much more risky because the institution could easily detect what was a-foot AND could reach-out and grab the miscreants for suitable punishment. These days, the student and 'ghost-writer' could be continents apart - and far from the reach of 'justice'! My first job at the university was as a marker (grader, these days perhaps "teaching assistant"). After a date-due, I would receive hundreds of multi-page printouts of COBOL or FORTRAN, and results. (could fill a small suit-case!) A few days later, I would return to the lecturer and drop multiple distinct piles on his desk. The 'good pile' was the distinct and passing efforts. The 'bad pile' was distinct but failing results. The other piles were all 'copies' - each member of the pile (and there were often dozens) were essentially identical - but the different piles of 'copies' were differently characteristic. I was always grateful that I didn't have to (a) identify who was the original author whose work passed/failed, or (b) decide how to mark (grade) or punish such. He repeatedly gave me 'glowing recommendations' because of the revelation of my ability to 'see' such patterns (which habit one would expect from systems analysts and designers, so shouldn't be 'that' special!). So, "nothing new under the sun" then! -- Regards =dn ------------------------------ Subject: Digest Footer _______________________________________________ Tutor maillist? -? Tutor at python.org https://mail.python.org/mailman/listinfo/tutor ------------------------------ End of Tutor Digest, Vol 196, Issue 28 ************************************** From deepakdixit0001 at gmail.com Mon Jun 15 04:13:28 2020 From: deepakdixit0001 at gmail.com (Deepak Dixit) Date: Mon, 15 Jun 2020 13:43:28 +0530 Subject: [Tutor] i want a solution to my problem In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> Message-ID: Chirag, Add your connection code here with version details of OS, Python, sqlite library then only someone will be able to guide you about the issue. On Mon, Jun 15, 2020 at 1:25 PM Chirag Jain wrote: > module 'sqlite300.sqlite3' has no attribute 'connect' > I m getting this error even if I had changed the name of the file what > should I do to overcome this problem. > Thank you > > Sent from Mail for Windows 10 > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- *With Regards,* *Deepak Kumar Dixit* From alan.gauld at yahoo.co.uk Mon Jun 15 07:03:27 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 15 Jun 2020 12:03:27 +0100 Subject: [Tutor] i want a solution to my problem In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> Message-ID: On 15/06/2020 04:01, Chirag Jain wrote: > module 'sqlite300.sqlite3' has no attribute 'connect' What is the sqlite300 thing? A google search didn't show anything about it. And why are you using that rather than the sqlite3 module that is part of the standard library? We need some more background and especially some code plus the full error text not just a summary. OS and python versions too. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Mon Jun 15 07:16:04 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 15 Jun 2020 12:16:04 +0100 Subject: [Tutor] Tutor Digest, Vol 196, Issue 28 In-Reply-To: <729354972.640706.1592184871457@mail.yahoo.com> References: <729354972.640706.1592184871457@mail.yahoo.com> Message-ID: On 15/06/2020 02:34, Krish P via Tutor wrote: > Hi, thanks for your response. > I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file. > given is the code that I came up with: > def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB > ? ? f = open("data.txt", "r")? ? print(f.read()) > ? ??main() You need to post in plain text or the mail server screws up the indentation as above. However, even with that I have some questions: main() isn't really a main function it just prints a banner message, so calling it print_banner() or somesuch would make more sense. Where is the code that reads each number (or even a single number!) from the data file? the f.read() call will read the whole file into a string but after you print it it disappears because you don't store it anywhere. I would expect your code structure to look like: print banner open and read data file for each entry in data call syr() function on each data entry store and print result If you don't know how to do any of that let us know. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From david at graniteweb.com Mon Jun 15 09:34:23 2020 From: david at graniteweb.com (David Rock) Date: Mon, 15 Jun 2020 08:34:23 -0500 Subject: [Tutor] i want a solution to my problem In-Reply-To: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> References: <5ee6e46f.1c69fb81.cacca.ac2a@mx.google.com> Message-ID: <20200615133423.GA29904@apple.graniteweb.com> * Chirag Jain [2020-06-15 08:31]: > module 'sqlite300.sqlite3' has no attribute 'connect' As others have mentioned, we need more information/code to give an accurate assessment, but that particular message essentially means you have tried to use the following in some way: sqlite300.sqlite.connect and "connect" is not something contained in sqlite300.sqlite3, so it fails. A sample of your code using the above statement will help a lot in our understanding. You will need to look at the documentation of the module you are using (preferably with a link so we can look at it, too), or give us a full traceback (not just the last line of error) for us to guide further. -- David Rock david at graniteweb.com From john at johnweller.co.uk Mon Jun 15 10:21:48 2020 From: john at johnweller.co.uk (John Weller) Date: Mon, 15 Jun 2020 15:21:48 +0100 Subject: [Tutor] Advice Please Message-ID: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> I seek advice. I am writing an application to control the humidity in a building. I am new to Python but not programming. I have an external class provided by the hardware supplier which will access the hardware to obtain the temperature and humidity. I will create an instance of the class in the main part of the program then use it in a loop to get the data, process it and display it. Accessing the data and checking it will be done in a function which I want to return the two values and an error count. In the languages I am used to I would pass the parameters to the function by reference so as to be able to access the values outside the function however I understand that this is not available in Python. Can Python return multiple values, (return temperature, humidity)? If not I could make the variables global (not recommended but as these values are fundamental to the whole program then perhaps acceptable) or use a compound data structure such as a dictionary or create a class just to hold the data? My question is ? what do you recommend? Can anyone recommend a book that I can use as a reference to perhaps answer some question without having to bother you guys ?. I?ve looked at a few books but they all have failings ? most I have seen don?t have an index (essential) or their code examples are screenshots from Terminal with coloured text on a black background which I find difficult to read or their style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort of thing. A bit like the Three Bears, something not too technical but not too easy. ? TIA John John Weller 01380 723235 07976 393631 From joel.goldstick at gmail.com Mon Jun 15 16:19:56 2020 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 15 Jun 2020 16:19:56 -0400 Subject: [Tutor] Advice Please In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: On Mon, Jun 15, 2020 at 4:10 PM John Weller wrote: > I seek advice. I am writing an application to control the humidity in a > building. I am new to Python but not programming. I have an external > class provided by the hardware supplier which will access the hardware to > obtain the temperature and humidity. I will create an instance of the > class in the main part of the program then use it in a loop to get the > data, process it and display it. Accessing the data and checking it will > be done in a function which I want to return the two values and an error > count. In the languages I am used to I would pass the parameters to the > function by reference so as to be able to access the values outside the > function however I understand that this is not available in Python. Can > Python return multiple values, (return temperature, humidity)? If not I > could make the variables global (not recommended but as these values are > fundamental to the whole program then perhaps acceptable) or use a compound > data structure such as a dictionary or create a class just to hold the > data? My question is ? what do you recommend? > > > python can return multiple values: >>> def myfunc(): ... a = 5 ... b = 1 ... return a, b ... >>> print (myfunc()) (5, 1) >>> In this case python returns a tuple. you could also do something like x, y = myfunc() print(x, y) > Can anyone recommend a book that I can use as a reference to perhaps > answer some question without having to bother you guys ?. I?ve looked at > a few books but they all have failings ? most I have seen don?t have an > index (essential) or their code examples are screenshots from Terminal with > coloured text on a black background which I find difficult to read or their > style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort > of thing. A bit like the Three Bears, something not too technical but not > too easy. ? > > > > TIA > > > > John > > > > John Weller > > 01380 723235 > > 07976 393631 > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From david at graniteweb.com Mon Jun 15 16:23:30 2020 From: david at graniteweb.com (David Rock) Date: Mon, 15 Jun 2020 15:23:30 -0500 Subject: [Tutor] Advice Please In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: <20200615202330.GF29904@apple.graniteweb.com> * John Weller [2020-06-15 15:21]: > pass the parameters to the function by reference so as to be able to > access the values outside the function however I understand that this > is not available in Python. Can Python return multiple values, > (return temperature, humidity)? If not I could make the variables yes, it's possible to return multiple values temp, humidity = read_temp_humidity() Where the return statement within your function will look like: return temp, humidity > global (not recommended but as these values are fundamental to the > whole program then perhaps acceptable) or use a compound data > structure such as a dictionary or create a class just to hold the > data? My question is ? what do you recommend? Globals or returning a single dictionary would also work. Generally, I use a dict if there are going to be many element to return, and a tuple if only a few (eg, just temp and humidity as above). > Can anyone recommend a book that I can use as a reference to perhaps > answer some question without having to bother you guys ?. I?ve That's hard to do without more of a solid understanding of your tastes and needs. There's the Python Books list on python.org https://wiki.python.org/moin/PythonBooks There are several good web-based "books" as well "Dive Into Python" usually bubbles to the top: https://diveintopython3.net/ I honestly do most of my stuff searching within the online docs. -- David Rock david at graniteweb.com From stephen.m.smith at comcast.net Mon Jun 15 16:29:02 2020 From: stephen.m.smith at comcast.net (stephen.m.smith at comcast.net) Date: Mon, 15 Jun 2020 16:29:02 -0400 Subject: [Tutor] Advice Please In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: <00e701d64353$9c2fc050$d48f40f0$@comcast.net> Pretty easy to do if I understand your question. https://note.nkmk.me/en/python-function-return-multiple-values/ or https://www.geeksforgeeks.org/g-fact-41-multiple-return-values-in-python/ basically return (temperature, humidity) or return temperature, humidity Positional integrity maintained. -----Original Message----- From: Tutor On Behalf Of John Weller Sent: Monday, June 15, 2020 10:22 AM To: tutor at python.org Subject: [Tutor] Advice Please I seek advice. I am writing an application to control the humidity in a building. I am new to Python but not programming. I have an external class provided by the hardware supplier which will access the hardware to obtain the temperature and humidity. I will create an instance of the class in the main part of the program then use it in a loop to get the data, process it and display it. Accessing the data and checking it will be done in a function which I want to return the two values and an error count. In the languages I am used to I would pass the parameters to the function by reference so as to be able to access the values outside the function however I understand that this is not available in Python. Can Python return multiple values, (return temperature, humidity)? If not I could make the variables global (not recommended but as these values are fundamental to the whole program then perhaps acceptable) or use a compound data structure such as a dictionary or create a class just to hold the data? My question is ? what do you recommend? Can anyone recommend a book that I can use as a reference to perhaps answer some question without having to bother you guys ?. I?ve looked at a few books but they all have failings ? most I have seen don?t have an index (essential) or their code examples are screenshots from Terminal with coloured text on a black background which I find difficult to read or their style is too jokey, ?print(?Hello World?) ? now you are a programmer? sort of thing. A bit like the Three Bears, something not too technical but not too easy. ? TIA John John Weller 01380 723235 07976 393631 _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From krishp52 at rocketmail.com Mon Jun 15 23:22:54 2020 From: krishp52 at rocketmail.com (Krish P) Date: Tue, 16 Jun 2020 03:22:54 +0000 (UTC) Subject: [Tutor] Tutor Digest, Vol 196, Issue 30 In-Reply-To: References: Message-ID: <1024482361.1161186.1592277774873@mail.yahoo.com> please check the code, I am finding it difficult to open the data file to read data from it and then finding the Syracuse sequence Please see the data and code attached On Tuesday, June 16, 2020, 04:00:22 AM GMT+12, tutor-request at python.org wrote: Send Tutor mailing list submissions to ??? tutor at python.org To subscribe or unsubscribe via the World Wide Web, visit ??? https://mail.python.org/mailman/listinfo/tutor or, via email, send a message with subject or body 'help' to ??? tutor-request at python.org You can reach the person managing the list at ??? tutor-owner at python.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Tutor digest..." Today's Topics: ? 1. Re: Tutor Digest, Vol 196, Issue 28 (Alan Gauld) ? 2. Re: i want a solution to my problem (David Rock) ---------------------------------------------------------------------- Message: 1 Date: Mon, 15 Jun 2020 12:16:04 +0100 From: Alan Gauld To: tutor at python.org Subject: Re: [Tutor] Tutor Digest, Vol 196, Issue 28 Message-ID: Content-Type: text/plain; charset=utf-8 On 15/06/2020 02:34, Krish P via Tutor wrote: >? Hi, thanks for your response. > I not able to?generate the Syracuse sequence for each of those numbers in the data.txt file. > given is the code that I came up with: > def syr(x):? ? if x % 2 ==0:? ? ? ? return x/2? ? else:? ? ? ? return 3*x + 1??def main():? ? x = 50? ? print(x*"-") # Line Break (LB)? ? print("Program use Syracuse sequence to reach 1 from")? ? print("natural numbers by utilizing a set of data.")? ? print(x*"-") # LB > ? ? f = open("data.txt", "r")? ? print(f.read()) > ? ??main() You need to post in plain text or the mail server screws up the indentation as above. However, even with that I have some questions: main() isn't really a main function it just prints a banner message, so calling it print_banner() or somesuch would make more sense. Where is the code that reads each number (or even a single number!) from the data file? the f.read() call will read the whole file into a string but after you print it it disappears because you don't store it anywhere. I would expect your code structure to look like: print banner open and read data file for each entry in data ? call syr() function on each data entry ? store and print result If you don't know how to do any of that let us know. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ------------------------------ Message: 2 Date: Mon, 15 Jun 2020 08:34:23 -0500 From: David Rock To: tutor at python.org Subject: Re: [Tutor] i want a solution to my problem Message-ID: <20200615133423.GA29904 at apple.graniteweb.com> Content-Type: text/plain; charset=us-ascii * Chirag Jain [2020-06-15 08:31]: > module 'sqlite300.sqlite3' has no attribute 'connect' As others have mentioned, we need more information/code to give an accurate assessment, but that particular message essentially means you have tried to use the following in some way: sqlite300.sqlite.connect and "connect" is not something contained in sqlite300.sqlite3, so it fails.? A sample of your code using the above statement will help a lot in our understanding. You will need to look at the documentation of the module you are using (preferably with a link so we can look at it, too), or give us a full traceback (not just the last line of error) for us to guide further. -- David Rock david at graniteweb.com ------------------------------ Subject: Digest Footer _______________________________________________ Tutor maillist? -? Tutor at python.org https://mail.python.org/mailman/listinfo/tutor ------------------------------ End of Tutor Digest, Vol 196, Issue 30 ************************************** -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: data.txt URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Assign3_S11048116.py URL: From alan.gauld at yahoo.co.uk Tue Jun 16 04:05:51 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Jun 2020 09:05:51 +0100 Subject: [Tutor] Tutor Digest, Vol 196, Issue 30 In-Reply-To: <1024482361.1161186.1592277774873@mail.yahoo.com> References: <1024482361.1161186.1592277774873@mail.yahoo.com> Message-ID: First, please do not send the entire digest. We have all seen these messages already and some people pay for their data by the byte. Also it is better to send code in-line (using plain text format) since the server strips attachments which it deems security threats. On 16/06/2020 04:22, Krish P via Tutor wrote: > please check the code, I am finding it difficult to open the data file to read data from it The code is a syr() function that should work. But it makes no attempt to open a file, read the contents or process the data. The previous program code opened the file and printed it. You need to store the data and split it into its constituent numbers. But we can only help you fix code that we can see. It's impossible to guess what you are doing wrong if we can't see the code that is broken. I've included your function below for the archive. ################################# def printCollatz(x): # We simply follow steps # while we do not reach 1 while x != 1: print(x, end = ' ') # If x is odd if x & 1: x = 3 * x + 1 # If even else: x = x // 2 # Print 1 at the end print(x) ############################## -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Mon Jun 8 20:12:26 2020 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 9 Jun 2020 01:12:26 +0100 Subject: [Tutor] What are the benefits of template or abstract base classes? In-Reply-To: References: <20200608030250.GF10604@Dream-Machine1> Message-ID: <1af601fb-89f3-2f66-ece5-98c0efd6e6eb@btinternet.com> On 08/06/2020 19:00, boB Stepp wrote: > I did receive the original email prior to it appearing on the Tutor Archive. Glad it went somewhere. It certainly never showed up on the list! > Hmm. Then ABCs seem quite useful. I wonder why I normally only see > mention of them as being advanced features? I guess because the vast majority of folks using classes don't really build OOP programs, they build procedural programs that use classes and objects as "smart data". And thats how many beginner tutorials (including mine) teach it. But if you read some of the more advanced OOP and especially OOD books/tutorials you will see a lot more on using ABC/virtual classes. A good example of one such is Grady Booch's book. > they would seem very useful for anything beyond small, simple OO > programs. Definitely more useful when you get to something with, say, double-digit number of classes. I'd say at least 4 or 5 to make much sense of it. > ...with mixins its normally a case >> of partially implemented classes rather than pure abstracts >> - what C++ calls virtual classes. > > So these concepts are language-agnostic and broadly used? Absolutely. They are a fundamental part of the OOP paradigm. Almost all OOD techniques work along the lines of: 0) identify requirements as a set of use cases and user stories 1) identify classes and responsibilities 2) identify is-a commonality between classes and represent generalized versions as ABC (Person, Shape, Network, Form, Request, transaction, etc) 3) create a high level framework solving the problem using only the ABCs. (include has-a and uses relationships) 4) build sufficient concrete classes to test the framework with 1 scenario/story 5) build more concrete classes, test another scenario or story. 6) repeat 5 until done. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From john at johnweller.co.uk Tue Jun 16 04:04:21 2020 From: john at johnweller.co.uk (John Weller) Date: Tue, 16 Jun 2020 09:04:21 +0100 Subject: [Tutor] Advice Please In-Reply-To: <20200615202330.GF29904@apple.graniteweb.com> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <20200615202330.GF29904@apple.graniteweb.com> Message-ID: <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk> Many thanks to all who replied - problem solved!! John John Weller 01380 723235 07976 393631 -----Original Message----- From: Tutor On Behalf Of David Rock Sent: 15 June 2020 21:24 To: tutor at python.org Subject: Re: [Tutor] Advice Please * John Weller [2020-06-15 15:21]: > pass the parameters to the function by reference so as to be able to > access the values outside the function however I understand that this > is not available in Python. Can Python return multiple values, > (return temperature, humidity)? If not I could make the variables yes, it's possible to return multiple values temp, humidity = read_temp_humidity() Where the return statement within your function will look like: return temp, humidity > global (not recommended but as these values are fundamental to the > whole program then perhaps acceptable) or use a compound data > structure such as a dictionary or create a class just to hold the > data? My question is ? what do you recommend? Globals or returning a single dictionary would also work. Generally, I use a dict if there are going to be many element to return, and a tuple if only a few (eg, just temp and humidity as above). > Can anyone recommend a book that I can use as a reference to perhaps > answer some question without having to bother you guys ?. I?ve That's hard to do without more of a solid understanding of your tastes and needs. There's the Python Books list on python.org https://wiki.python.org/moin/PythonBooks There are several good web-based "books" as well "Dive Into Python" usually bubbles to the top: https://diveintopython3.net/ I honestly do most of my stuff searching within the online docs. -- David Rock david at graniteweb.com _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Tue Jun 16 11:17:42 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Jun 2020 16:17:42 +0100 Subject: [Tutor] Advice Please In-Reply-To: <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <20200615202330.GF29904@apple.graniteweb.com> <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk> Message-ID: On 16/06/2020 09:04, John Weller wrote: > Many thanks to all who replied - problem solved!! Just one other point that i don;t think anyone else picked up specifically. >> pass the parameters to the function by reference so as to be able to >> access the values outside the function however I understand that this >> is not available in Python. Python is closer to pass by reference than it is to pass by value. In python variables(and that includes function parameters) are merely names that refer to objects. So a function parameter is a name to which an object can be attached. If that object is mutable (list, dict, class etc) you can change it inside the function and the change will be apparent outside the function too. If its immutable a new value will be created and assigned to the parameter name but the original variable will still refer to the original object. Once you get used to that idea it all makes sense but for beginners to the language it is quite different to how most languages work. Here is an example: def changeSeq(seq): seq[0] = 42 # mutable list return seq lst = [1,2,3] changeSeq(lst) print(lst) -> [42,2,3] def changeVal(val): val = 42 # immutable integer return val x = 66 changeVal(x) print(x) -> 66 Of course the cleanest way is always to reassign the function return value. In both cases above: lst = changeSeq(lst) -> [42,2,3] x = changeVal(x) -> 42 This is not an expensive option since the objects are not being copied, it is just a reassignment of the reference in both cases. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From david at graniteweb.com Tue Jun 16 12:36:54 2020 From: david at graniteweb.com (David Rock) Date: Tue, 16 Jun 2020 11:36:54 -0500 Subject: [Tutor] Advice Please In-Reply-To: References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <20200615202330.GF29904@apple.graniteweb.com> <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk> Message-ID: <20200616163654.GC7284@apple.graniteweb.com> * Alan Gauld via Tutor [2020-06-16 16:17]: > On 16/06/2020 09:04, John Weller wrote: > > Many thanks to all who replied - problem solved!! > > Python is closer to pass by reference than it is to pass by value. > In python variables(and that includes function parameters) are > merely names that refer to objects. So a function parameter is > a name to which an object can be attached. > > If that object is mutable (list, dict, class etc) you can change > it inside the function and the change will be apparent outside the > function too. If its immutable a new value will be created and > assigned to the parameter name but the original variable will > still refer to the original object. That's a good callout, Alan. There's a summary of the OP question in the FAQ, as well: https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference -- David Rock david at graniteweb.com From annametreveli at gmail.com Tue Jun 16 18:40:39 2020 From: annametreveli at gmail.com (Anna Metreveli) Date: Wed, 17 Jun 2020 00:40:39 +0200 Subject: [Tutor] help with twitter API Message-ID: Hi, everyone I'm doing a small study in sociolinguistics and currently struggling with Twitter API. I want to collect tweets with animated GIFS. I tried using filter: images when initializing Tweepy API: API = tweepy.API(auth) results = api.search(q=" filter:images", lang="en") but I am out of ideas about how to sort out GIFs from that by using the extended_enteties/media/type with JSON where type is "animated_gif". Thank you! From PyTutor at danceswithmice.info Tue Jun 16 19:32:04 2020 From: PyTutor at danceswithmice.info (dn) Date: Wed, 17 Jun 2020 11:32:04 +1200 Subject: [Tutor] Advice Please In-Reply-To: References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <20200615202330.GF29904@apple.graniteweb.com> <002a01d643b4$c0430400$40c90c00$@johnweller.co.uk> Message-ID: <3ffd4250-9a09-4775-8db7-d06049a7555d@DancesWithMice.info> On 17/06/20 3:17 AM, Alan Gauld via Tutor wrote: > On 16/06/2020 09:04, John Weller wrote: >> Many thanks to all who replied - problem solved!! > > Just one other point that i don;t think anyone else > picked up specifically. > >>> pass the parameters to the function by reference so as to be able to >>> access the values outside the function however I understand that this >>> is not available in Python. > > Python is closer to pass by reference than it is to pass by value. > In python variables(and that includes function parameters) are > merely names that refer to objects. So a function parameter is > a name to which an object can be attached. > > If that object is mutable (list, dict, class etc) you can change > it inside the function and the change will be apparent outside the > function too. If its immutable a new value will be created and > assigned to the parameter name but the original variable will > still refer to the original object. > > Once you get used to that idea it all makes sense but for beginners > to the language it is quite different to how most languages work. > > Here is an example: > > def changeSeq(seq): > seq[0] = 42 # mutable list > return seq > > lst = [1,2,3] > changeSeq(lst) > print(lst) -> [42,2,3] > > > def changeVal(val): > val = 42 # immutable integer > return val > > x = 66 > changeVal(x) > print(x) -> 66 > > Of course the cleanest way is always to reassign the > function return value. In both cases above: > > lst = changeSeq(lst) -> [42,2,3] > x = changeVal(x) -> 42 > > This is not an expensive option since the objects are > not being copied, it is just a reassignment of the > reference in both cases. Recommend playing with the Python Tutor (http://www.pythontutor.com/). If you try these (earlier) snippets, it enables one to step-through the code whilst showing stack-frames and illustrating "scope". Some Python-editors offer a similar 'visual programming' experience. The term "variable" (which most of us 'bandy around' quite happily) has a substantively different meaning in Python (than it does in other languages), eg a name in Python will point to a value, but a name may not point to another name, ie: >>> a = 1 >>> b = a >>> a 1 >>> b 1 >>> a = 2 >>> a 2 >>> b 1 Similarly, when 'passing' data to a function, the parameters are separate names from the arguments. However, there is the major difference in behavior between mutable and immutable, which is frequently a major 'gotcha' for newcomers (per above). The illustration PythonTutor provides is a positive means of reinforcing this learning! Thus, many 'traditional' discussions of "pass by reference"/"pass by value" no longer apply, because neither quite applies. They don't have a place within the Python model. -- Regards =dn From bouncingcats at gmail.com Tue Jun 16 23:18:49 2020 From: bouncingcats at gmail.com (David) Date: Wed, 17 Jun 2020 13:18:49 +1000 Subject: [Tutor] Advice Please In-Reply-To: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: On Tue, 16 Jun 2020 at 06:11, John Weller wrote: [...] I am new to Python but not programming. [...] In the languages I am > used to I would pass the parameters to the function by reference [...] My > question is ? what do you recommend? > Hi John, In addition to the other replies, I strongly recommend you watch "Facts and Myths about Python names and values" [1], a presentation given at PyCon 2015 by Ned Batchelder, a very well regarded educator in the Python community. You can also search youtube for other presentations by Ned or Raymond Hettinger, they will greatly improve your Python insight beyond what you will find in the books and written documentation. Python is a beautiful language, but some of that beauty requires insights to appreciate, and the official docs don't do a great job of providing that in my experience. [1] https://www.youtube.com/watch?v=_AEJHKGk9ns From breamoreboy at gmail.com Tue Jun 16 23:50:49 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Wed, 17 Jun 2020 04:50:49 +0100 Subject: [Tutor] Advice Please In-Reply-To: References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: On 17/06/2020 04:18, David wrote: > On Tue, 16 Jun 2020 at 06:11, John Weller wrote: > > [...] I am new to Python but not programming. [...] In the languages I am >> used to I would pass the parameters to the function by reference [...] My >> question is ? what do you recommend? >> > > Hi John, > > In addition to the other replies, I strongly recommend you > watch "Facts and Myths about Python names and values" [1], > a presentation given at PyCon 2015 by Ned Batchelder, a > very well regarded educator in the Python community. > > You can also search youtube for other presentations by Ned > or Raymond Hettinger, they will greatly improve your Python > insight beyond what you will find in the books and written > documentation. > > Python is a beautiful language, but some of that beauty > requires insights to appreciate, and the official docs don't > do a great job of providing that in my experience. > > [1] https://www.youtube.com/watch?v=_AEJHKGk9ns Another resource https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/ -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From john at johnweller.co.uk Wed Jun 17 05:44:11 2020 From: john at johnweller.co.uk (John Weller) Date: Wed, 17 Jun 2020 10:44:11 +0100 Subject: [Tutor] Advice Please In-Reply-To: References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> Thanks guys for all your help and advice, I am constantly impressed by your obvious passion for the language and willingness to freely give of your time and expertise to help others. I am also surprised by the large, sometimes overwhelming, amount of information available - my problem is finding it and then sorting the wheat from the chaff ? I was first taught to program using a variant of Dartmouth Basic on a mainframe in 1976 as part of a postgraduate navigation course in the RAF. I progressed through Algol, Fortran, Pascal, etc and earnt my living after I left the service with FoxPro. I retired 15 years ago but earlier this year I bought a Raspberry Pi and an electronics kit which came with code in Python and C so I had to learn one of them. I am now hooked on Python but seem to spend my time taking two steps forward then between one and three back! Thanks again for all your help. John John Weller 01380 723235 07976 393631 From johnf at jfcomputer.com Wed Jun 17 08:52:13 2020 From: johnf at jfcomputer.com (john) Date: Wed, 17 Jun 2020 05:52:13 -0700 Subject: [Tutor] Advice Please In-Reply-To: <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> Message-ID: <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com> On 6/17/20 2:44 AM, John Weller wrote: > Thanks guys for all your help and advice, I am constantly impressed by your obvious passion for the language and willingness to freely give of your time and expertise to help others. I am also surprised by the large, sometimes overwhelming, amount of information available - my problem is finding it and then sorting the wheat from the chaff ? I was first taught to program using a variant of Dartmouth Basic on a mainframe in 1976 as part of a postgraduate navigation course in the RAF. I progressed through Algol, Fortran, Pascal, etc and earnt my living after I left the service with FoxPro. I retired 15 years ago but earlier this year I bought a Raspberry Pi and an electronics kit which came with code in Python and C so I had to learn one of them. I am now hooked on Python but seem to spend my time taking two steps forward then between one and three back! > > Thanks again for all your help. > > John > > John Weller > 01380 723235 > 07976 393631 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor I noticed that you once used FoxPro.? You might want to checkout Dabo (https://dabodev.com/). Dabo is python's answer to foxpro.? It works in general with python 3.x and wxPython 4.x but some items are not working correctly.? I have been working on moving to the latest wxPython 4.1.x.? There are several branches on github (dabo3-4.1 is my branch). git clone git at github.com:dabodev/dabo.git Good luck, Johnf From alan.gauld at btinternet.com Wed Jun 17 13:47:49 2020 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 17 Jun 2020 18:47:49 +0100 Subject: [Tutor] Advice Please In-Reply-To: <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com> Message-ID: <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com> On 17/06/2020 13:52, john wrote: > I noticed that you once used FoxPro.? You might want to checkout Dabo > (https://dabodev.com/). Dabo is python's answer to foxpro.? I'm glad to hear Dabo is still going strong. A few years back I investigated all the GUI builder tools I could find for python. Dabo was one of the best. At that time it was tricky to make it work with other databases but they had plans to fix that. But at the time i needed SqlLite integration so I passed. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From guroanne at gmail.com Thu Jun 18 04:53:34 2020 From: guroanne at gmail.com (=?UTF-8?Q?Guro_Anne_Br=C3=A6kken?=) Date: Thu, 18 Jun 2020 10:53:34 +0200 Subject: [Tutor] obspy.imaging.spectrogram Message-ID: Hi there, Is there anyone out there who would know how to output the data from the obspy function spectrogram (and not only an image file)? Problem: 1.read in one seismic trace (SEGY format) - OK 2. calculate and plot the spectrogram using obspy.imaging.spectrogram - OK 3. output the image of the spectrogram as a PNG file - OK 4. output the data points in SEGY format - NOT POSSIBLE ?? My code is the following: st=obspy.read(\seismic\trace.segy) st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9, outfile="st_spec_image") st_spec.write('st_spec_data', format='SEGY') I am running the code with Anaconda navigator and python 3.7.6 I hope this was clear. Looking forward to hearing about programmers' experiences with this issue! Kind regards, Guro Anne Braekken From alan.gauld at yahoo.co.uk Thu Jun 18 05:35:05 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 18 Jun 2020 10:35:05 +0100 Subject: [Tutor] obspy.imaging.spectrogram In-Reply-To: References: Message-ID: On 18/06/2020 09:53, Guro Anne Br?kken wrote: > Hi there, > > Is there anyone out there who would know how to output the data from the > obspy function spectrogram (and not only an image file)? > This is a pretty specialized question for a general group like tutor especially since its not a standard library package. I suggest reaching out to the folks on the SciPy forum, they are more likely to include users of obspy. There is also an obspy mailing list: http://lists.obspy.org/cgi-bin/mailman/listinfo/obspy-users > My code is the following: I hope not! > st=obspy.read(\seismic\trace.segy) The filename should be in quotes and, since you use backslashes prepended with an 'r' > st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9, > outfile="st_spec_image") > st_spec.write('st_spec_data', format='SEGY' -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From john at johnweller.co.uk Thu Jun 18 07:09:52 2020 From: john at johnweller.co.uk (John Weller) Date: Thu, 18 Jun 2020 12:09:52 +0100 Subject: [Tutor] Advice Please In-Reply-To: References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> Message-ID: <002601d64560$fea0b410$fbe21c30$@johnweller.co.uk> Excellent video, explains a lot! Interesting behaviour ? Thanks John John Weller 01380 723235 07976 393631 -----Original Message----- From: Tutor On Behalf Of David Sent: 17 June 2020 04:19 To: Python Tutor Subject: Re: [Tutor] Advice Please On Tue, 16 Jun 2020 at 06:11, John Weller wrote: [...] I am new to Python but not programming. [...] In the languages I am > used to I would pass the parameters to the function by reference [...] > My question is ? what do you recommend? > Hi John, In addition to the other replies, I strongly recommend you watch "Facts and Myths about Python names and values" [1], a presentation given at PyCon 2015 by Ned Batchelder, a very well regarded educator in the Python community. You can also search youtube for other presentations by Ned or Raymond Hettinger, they will greatly improve your Python insight beyond what you will find in the books and written documentation. Python is a beautiful language, but some of that beauty requires insights to appreciate, and the official docs don't do a great job of providing that in my experience. [1] https://www.youtube.com/watch?v=_AEJHKGk9ns _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From john at johnweller.co.uk Thu Jun 18 07:36:06 2020 From: john at johnweller.co.uk (John Weller) Date: Thu, 18 Jun 2020 12:36:06 +0100 Subject: [Tutor] Advice Please In-Reply-To: <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com> <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com> Message-ID: <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk> I didn't get John's original posting about Dabo (or maybe I lost it). I was aware of Dabo as it was written by Ed Leafe who runs the ProFox email list which I have been a member of for over 20 years. Profox is a very friendly, helpful list and I'm getting the same warm feeling about this one ? I bought a Raspberry Pi and an electronics kit just before lockdown, did some Future Learn courses on Python and one on HTML, etc and have booked one on robotics - I have found so many options and paths I want to follow I'm spoilt for choice! Regards John John Weller 01380 723235 07976 393631 -----Original Message----- From: Tutor On Behalf Of Alan Gauld via Tutor Sent: 17 June 2020 18:48 To: tutor at python.org Cc: Alan Gauld Subject: Re: [Tutor] Advice Please On 17/06/2020 13:52, john wrote: > I noticed that you once used FoxPro. You might want to checkout Dabo > (https://dabodev.com/). Dabo is python's answer to foxpro. I'm glad to hear Dabo is still going strong. A few years back I investigated all the GUI builder tools I could find for python. Dabo was one of the best. At that time it was tricky to make it work with other databases but they had plans to fix that. But at the time i needed SqlLite integration so I passed. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From bouncingcats at gmail.com Thu Jun 18 11:13:32 2020 From: bouncingcats at gmail.com (David) Date: Fri, 19 Jun 2020 01:13:32 +1000 Subject: [Tutor] Advice Please In-Reply-To: <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk> References: <009101d64320$4f2f4240$ed8dc6c0$@johnweller.co.uk> <002601d6448b$dcafa5d0$960ef170$@johnweller.co.uk> <97a79e3f-a7ab-2123-0398-27b9bb4af204@jfcomputer.com> <69911492-6c2e-12b4-4597-12955f7bf648@btinternet.com> <006c01d64564$aad7e4d0$0087ae70$@johnweller.co.uk> Message-ID: On Thu, 18 Jun 2020 at 23:00, John Weller wrote: I didn't get John's original posting about Dabo (or maybe I lost it). > You can read it here: https://mail.python.org/pipermail/tutor/2020-June/116773.html By the way, like many mailing lists, we prefer interleaved replies here so please don't top-post, and please trim your replies, more info here: https://en.wikipedia.org/wiki/Posting_style#Trimming_and_reformatting https://en.wikipedia.org/wiki/Posting_style#Interleaved_style https://en.wikipedia.org/wiki/Posting_style#Top-posting Thanks! From guroanne at gmail.com Thu Jun 18 09:36:39 2020 From: guroanne at gmail.com (=?UTF-8?Q?Guro_Anne_Br=C3=A6kken?=) Date: Thu, 18 Jun 2020 15:36:39 +0200 Subject: [Tutor] obspy.imaging.spectrogram In-Reply-To: References: Message-ID: Hi Again, Unfortunately I forgot to mention the error message, it is the following: AttributeError Traceback (most recent call last) in ----> 1 st_spec.write('st_spec_data', format='SEGY') AttributeError: 'list' object has no attribute 'write' The object type is "list", which does not make any sense since I will need floating point numbers....... Kind regards, Guro Anne Br?kken On Thu, Jun 18, 2020 at 10:53 AM Guro Anne Br?kken wrote: > Hi there, > > Is there anyone out there who would know how to output the data from the > obspy function spectrogram (and not only an image file)? > > Problem: > 1.read in one seismic trace (SEGY format) - OK > 2. calculate and plot the spectrogram using obspy.imaging.spectrogram - OK > 3. output the image of the spectrogram as a PNG file - OK > 4. output the data points in SEGY format - NOT POSSIBLE ?? > > My code is the following: > st=obspy.read(\seismic\trace.segy) > st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9, > outfile="st_spec_image") > st_spec.write('st_spec_data', format='SEGY') > > I am running the code with Anaconda navigator and python 3.7.6 > > I hope this was clear. Looking forward to hearing about programmers' > experiences with this issue! > > Kind regards, > Guro Anne Braekken > > > From alan.gauld at yahoo.co.uk Thu Jun 18 13:07:41 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 18 Jun 2020 18:07:41 +0100 Subject: [Tutor] obspy.imaging.spectrogram In-Reply-To: References: Message-ID: On 18/06/2020 14:36, Guro Anne Br?kken wrote: > AttributeError Traceback (most recent call > last) in ----> 1 > st_spec.write('st_spec_data', format='SEGY') > AttributeError: 'list' object has no attribute 'write' > > The object type is "list", which does not make any sense since I will need > floating point numbers....... The list can hold anything but it's the list object that needs to have a write() method. And it doesn't. Looking again at your code: st=obspy.read(\seismic\trace.segy) st_spec=st.spectrogram(log=True, wlen=0.02, samp_rate=32000, per_lap=0.9, outfile="st_spec_image") st_spec is the return value from st.spectrogram() and it seems reasonable that spectrogram() would return a list of values. Although I don't know what the outfile parameter does in that case! This is probably what you need to ask the obspy community. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From maryknauth at mac.com Fri Jun 19 10:44:17 2020 From: maryknauth at mac.com (Mary Knauth) Date: Fri, 19 Jun 2020 10:44:17 -0400 Subject: [Tutor] Input parameters for functions Message-ID: Hello Everyone, I have a script for a school assignment, an ATM transaction script based on the purpose of creating functions. The draft I submitted all worked fine, but the feedback from my instructor was that I needed to use parameters in my functions. Questions: My original py script worked 100% with no parameters in the functions, so what is the advantage of adding the parameters? I have put in what I think should be the parameters in my new py file, all the functions work, but do you think I have utilized the parameters correctly? def balance(account_balance) def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary? def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary? Many thanks in advance for your insight and thoughts. Warm Regards, Mary Knauth 954-412-9280 maryknauth at mac.com http://www.zephyrsolutions.us From david at graniteweb.com Fri Jun 19 19:04:28 2020 From: david at graniteweb.com (David Rock) Date: Fri, 19 Jun 2020 18:04:28 -0500 Subject: [Tutor] Input parameters for functions In-Reply-To: References: Message-ID: <20200619230428.GN7425@apple.graniteweb.com> * Mary Knauth via Tutor [2020-06-19 10:44]: > Hello Everyone, > > I have a script for a school assignment, an ATM transaction script > based on the purpose of creating functions. The draft I submitted all > worked fine, but the feedback from my instructor was that I needed to > use parameters in my functions. > > Questions: > My original py script worked 100% with no parameters in the functions, so > what is the advantage of adding the parameters? I have put in what I think > should be the parameters in my new py file, all the functions work, but do > you think I have utilized the parameters correctly? > > Many thanks in advance for your insight and thoughts. Hello, Mary. Welcome! > My original py script worked 100% with no parameters in the functions, so > what is the advantage of adding the parameters? The advantage of using parameters is it allows you to feed information to the functions so it can be used with more than one static case. For example, your deposit function can be called with different values to allow the same function to be used for any deposit amount, not just a hard-coded amount. > def balance(account_balance) > def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary? > def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary? If you included your .py file, it probably got stripped. The email list does not normally accept any attachments. Please send the text of the file inside the body of the email if you want us to look at it. That said, account_balance is probably necessary in all cases because both deposit and withdrawal functions have two pieces of information they need to be successful: the account balance, and the dollar amount you wish to add/subtract. It looks to me like you are on the right track. :-) -- David Rock david at graniteweb.com From david at graniteweb.com Fri Jun 19 19:47:27 2020 From: david at graniteweb.com (David Rock) Date: Fri, 19 Jun 2020 18:47:27 -0500 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] Message-ID: <20200619234727.GO7425@apple.graniteweb.com> Mary, I've forwarded your reply to the mailing list. Remember to reply to the list email and not individuals so others can see the conversation (both to help and to learn). Comments inline below > ----- Forwarded message from Mary Knauth ----- > > Hello David, > > Thanks very much for the welcome, I?ve written a couple question so far to the > python tutor group, and it?s amazing what knowledge you all give back, so thank > you! > > Here is my code: > > import sys > > # -------------------------- DECLARE variables for balance, deposit, and withdrawal -------------------------- > > account_balance = float(500.25) # Starting balance indicated by Codio > deposit_amount = 0 # Declare variable 'deposit_amount' > withdrawal_amount = 0 # Declare variable 'withdrawal_amount' > > > # -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit ----------------------------- > > def balance(account_balance): # Define balance function > print("Your current balance: ", account_balance) # Prints the current avalible balance > > def deposit(account_balance, deposit_amount): # Define DEPOSIT function with parameters account_balance and deposit_amount > deposit_amount = float(input("How much would you like to deposit today?\n")) # Accept user input for the deposit amount, in float format > balance = account_balance + deposit_amount # This addition assigns the updated value of the account blance, to the variable 'BALANCE' > print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, balance)) # Prints depost amount and account balance > > def withdrawal(account_balance, withdrawal_amount): # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount > withdrawal_amount = float(input("How much would you like to withdraw today?\n")) # Accept user input for the withdrawal amount, in float format > if withdrawal_amount > account_balance: # Checking to see if the amount requested, is greater than the amount avalible > print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds > else: # Suffient amount of funds are avalible, the function continues > balance = account_balance - withdrawal_amount # Variable 'balance' is assigned to reflect the new avalible balance > print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, balance)) # Prints withdrawal amount and account balance These are mostly fine for individual use-cases, but all they do is print the temporary updated value. For deposit and withdrawal, do you have a requirement to remember the new values? How would you update the global variables with the new values from the functions to make them persistent? > # ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q ------------------------------------- > userChoice = 'go' # Setting the variable 'userChoice' to 'go', so we can impliment a while loop > > while userChoice != 'E': # As long as the user does not select 'E' (Exit), the program will keep looping with user choices > > # Step ONE => Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice' > userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper() > > # Step TWO => conditional statement begins based on the value of variable 'userchoice' from user input > # Four branches ustilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT > if (userChoice == 'D'): # Accepts input D and proceeds with function 'deposit' > deposit (account_balance, deposit_amount) # DEPOSIT function is called with parameters 'account_balance' and 'deposit_amount' > > elif (userChoice == 'B'): # Accepts input B and proceeds with function 'balance' > balance (account_balance) # BALANCE function is called with parameter 'account_balance' > > elif (userChoice == 'W'): # Accepts input D and proceeds with function 'withdrawal' > withdrawal (account_balance, withdrawal_amount) # WITHDRAWAL function is called with parameters 'account_balance' and 'withdrawal_amount' > > elif (userChoice == 'E'): # Accepts input E for EXIT > print("Thank you for banking with us.") # There is no function for EXIT, and therefore the user has a printed message ending their session Overall, This is structured just fine. The main thing I would look at is what I mentioned above regarding value permanence. To see what I mean, run the program, but make several transactions in a row. If you subtract $100 and then check your balance, does it change? If not, how would you fix it? -- David Rock david at graniteweb.com From alan.gauld at yahoo.co.uk Fri Jun 19 19:49:20 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 20 Jun 2020 00:49:20 +0100 Subject: [Tutor] Input parameters for functions In-Reply-To: References: Message-ID: On 19/06/2020 15:44, Mary Knauth via Tutor wrote: > My original py script worked 100% with no parameters in the functions, > so what is the advantage of adding the parameters? To answer that we have to go back to basics and ask why write functions in the first place? There are basically two reasons_ a) The save us having to retype code every time we need it, we can just call the function. b) We can reuse code in more than one program. Think about the standard library modules that you have probably used. eg. We can import sys and then use the functions (like exit) that are inside sys in every program. c) They make our code easier to read by hiding the details of an operation. That doesn't really depend so much on parameters, although it can help, but we will ignore it as an issue for now. For case (a) it doesn't matter so much whether we use parameters or not. It's our code, we know what it is doing. We can use global variables and we know what those variables are called. No problem.(Although if you need to use it on different values within your program things change, as you'll see below) But in case (b) if we don't have parameters we must still rely on global variables. And that means we must know the names of those variables. But if the code that is calling our function is in a different program how can we be sure it has the same variable names? Or worse, that if it does use the same names that it uses them the same way we did when we wrote the function? Consider a simple function that calculates the square of a number: def square() return x*x Now that will work fine if we have a variable called x. But if I try to import the code and use the square function in another program I need to create a variable in my program called x otherwise the function will fail. But the only way I know to do that is if I read your code. Easy in this case but imagine if the function had several dozen (or hundred) lines of code inside! (Which is common in professional size programs) Now see what changes if we rewrite square using a parameter: def square(x): return x*x Now I can import your code and pass it any variable name I like: import mary_code z = 42 print(mary_code.square(z)) y = 27 print(mary_code.square(y)) Notice I called square twice. The first time I passed a variable called z, the second time I passed y. Without the parameter I can't do that, I have to use x so the equivalent code becomes: import mary_code z = 42 y = 22 x = z print(mary_code.square()) x = y print(mary_code.square()) Notice how I have to introduce an x value then copy the values I want to use (z and y) into x before I can call the function. Now imagine I already have a variable called x that I'm using for something else. Now it gets really messy. I have to copy x to a temporary variable. Then copy my real variable (z or y) to x. then call the function. Then copy the temporary variable back into x. And I have to do that every time I try to use the function. Pretty soon the function is causing more work than it saves! That's why its a good idea to make your functions like standalone pieces of code with no dependencies on the external code that calls them. Then you can use them across many projects, or with many values in your own project. > def balance(account_balance) > def deposit(account_balance, deposit_amount) ???----??is ?account_balance? necessary? > def withdrawal(account_balance, withdrawal_amount) ?? is ?account_balance? necessary? Yes that looks right. The deposit and withdrawal functions need to know the starting balance and the amount. They can then return the ending balance. The first function may not be necessary if it just returns the value given to it! But if it prints a nice message or checks it is not negative or something then in that case it would be sensible to tell it what the balance was. (Although we might rename it to print_balance() or check_balance() perhaps) Note: There are other problems associated with using global variables in functions but they require much more complex examples and only really apply to large programs so we can ignore them for now. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From maryknauth at mac.com Sat Jun 20 09:08:27 2020 From: maryknauth at mac.com (Mary Knauth) Date: Sat, 20 Jun 2020 09:08:27 -0400 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: <20200619234727.GO7425@apple.graniteweb.com> References: <20200619234727.GO7425@apple.graniteweb.com> Message-ID: David, Thank you, I?ll remember to reply to the list from now on :) You actually touched down on another question I had in my head, the value of accout_balance is temporary just as you stated. I think I need to add return to my functions. ?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return. Correct? Warm Regards, Mary Knauth 954-412-9280 maryknauth at mac.com > On Jun 19, 2020, at 7:47 PM, David Rock wrote: > > ?Mary, > > I've forwarded your reply to the mailing list. Remember to reply to the list > email and not individuals so others can see the conversation (both to help and > to learn). Comments inline below > >> ----- Forwarded message from Mary Knauth ----- >> >> Hello David, >> >> Thanks very much for the welcome, I?ve written a couple question so far to the >> python tutor group, and it?s amazing what knowledge you all give back, so thank >> you! >> >> Here is my code: >> >> import sys >> >> # -------------------------- DECLARE variables for balance, deposit, and withdrawal -------------------------- >> >> account_balance = float(500.25) # Starting balance indicated by Codio >> deposit_amount = 0 # Declare variable 'deposit_amount' >> withdrawal_amount = 0 # Declare variable 'withdrawal_amount' >> >> >> # -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit ----------------------------- >> >> def balance(account_balance): # Define balance function >> print("Your current balance: ", account_balance) # Prints the current avalible balance >> >> def deposit(account_balance, deposit_amount): # Define DEPOSIT function with parameters account_balance and deposit_amount >> deposit_amount = float(input("How much would you like to deposit today?\n")) # Accept user input for the deposit amount, in float format >> balance = account_balance + deposit_amount # This addition assigns the updated value of the account blance, to the variable 'BALANCE' >> print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, balance)) # Prints depost amount and account balance >> >> def withdrawal(account_balance, withdrawal_amount): # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount >> withdrawal_amount = float(input("How much would you like to withdraw today?\n")) # Accept user input for the withdrawal amount, in float format >> if withdrawal_amount > account_balance: # Checking to see if the amount requested, is greater than the amount avalible >> print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds >> else: # Suffient amount of funds are avalible, the function continues >> balance = account_balance - withdrawal_amount # Variable 'balance' is assigned to reflect the new avalible balance >> print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, balance)) # Prints withdrawal amount and account balance > > > These are mostly fine for individual use-cases, but all they do is print > the temporary updated value. For deposit and withdrawal, do you have a > requirement to remember the new values? How would you update the global > variables with the new values from the functions to make them persistent? > > >> # ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q ------------------------------------- >> userChoice = 'go' # Setting the variable 'userChoice' to 'go', so we can impliment a while loop >> >> while userChoice != 'E': # As long as the user does not select 'E' (Exit), the program will keep looping with user choices >> >> # Step ONE => Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice' >> userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper() >> >> # Step TWO => conditional statement begins based on the value of variable 'userchoice' from user input >> # Four branches ustilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT >> if (userChoice == 'D'): # Accepts input D and proceeds with function 'deposit' >> deposit (account_balance, deposit_amount) # DEPOSIT function is called with parameters 'account_balance' and 'deposit_amount' >> >> elif (userChoice == 'B'): # Accepts input B and proceeds with function 'balance' >> balance (account_balance) # BALANCE function is called with parameter 'account_balance' >> >> elif (userChoice == 'W'): # Accepts input D and proceeds with function 'withdrawal' >> withdrawal (account_balance, withdrawal_amount) # WITHDRAWAL function is called with parameters 'account_balance' and 'withdrawal_amount' >> >> elif (userChoice == 'E'): # Accepts input E for EXIT >> print("Thank you for banking with us.") # There is no function for EXIT, and therefore the user has a printed message ending their session > > > Overall, This is structured just fine. The main thing I would look at > is what I mentioned above regarding value permanence. To see what I > mean, run the program, but make several transactions in a row. If you > subtract $100 and then check your balance, does it change? If not, how > would you fix it? > > > -- > David Rock > david at graniteweb.com > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sat Jun 20 11:00:18 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 20 Jun 2020 16:00:18 +0100 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: References: <20200619234727.GO7425@apple.graniteweb.com> Message-ID: On 20/06/2020 14:08, Mary Knauth via Tutor wrote: > I think I need to add return to my functions. That's correct. > ?return account_balance = account_balance + deposit_amount? is an invalid syntax, Yes. You cannot combine assignment and another statement such as return. (In the latest versions of Python there is a new feature that does allow this but we will ignore that for now!) You need to calculate the value first then return it. account_balance = account_balance + deposit_amount # possibly do more things with account_balance return account_balance If you don;t need to do anything with account_balance you can return the calculation result directly: return account_balance + deposit_amount You may find the "Modules and Functions" topic of my tutorial helpful. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/l2p2 http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Sat Jun 20 11:17:23 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 20 Jun 2020 09:17:23 -0600 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: References: <20200619234727.GO7425@apple.graniteweb.com> Message-ID: <272ed428-ac78-8288-8d59-9628108f977b@wichmann.us> On 6/20/20 9:00 AM, Alan Gauld via Tutor wrote: > On 20/06/2020 14:08, Mary Knauth via Tutor wrote: >> I think I need to add return to my functions. > > That's correct. > >> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, > > Yes. You cannot combine assignment and another statement such as return. > (In the latest versions of Python there is a new feature that does allow > this but we will ignore that for now!) > > You need to calculate the value first then return it. > > account_balance = account_balance + deposit_amount > # possibly do more things with account_balance > return account_balance > > > If you don;t need to do anything with account_balance you can return the > calculation result directly: > > return account_balance + deposit_amount > > You may find the "Modules and Functions" topic of my tutorial helpful. I think you'll also find that this example will make more sense in a context that will come up later in your learning: a way to have persistent values that can be accessed by functions, without using global variables, will be laid out when the course gets on to classes and methods ("object oriented programming", although in Python it's all objects actually). Have to lay the foundation first, though. From alexkleider at protonmail.com Sat Jun 20 11:23:31 2020 From: alexkleider at protonmail.com (alexkleider) Date: Sat, 20 Jun 2020 15:23:31 +0000 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: References: <20200619234727.GO7425@apple.graniteweb.com> Message-ID: ??????? Original Message ??????? On Saturday, June 20, 2020 6:08 AM, Mary Knauth via Tutor wrote: > > ?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return. Try account_balance += deposit_amount return account_balance or simply return account_balance + deposit_amount From maryknauth at mac.com Sat Jun 20 13:22:43 2020 From: maryknauth at mac.com (Mary Knauth) Date: Sat, 20 Jun 2020 13:22:43 -0400 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: References: <20200619234727.GO7425@apple.graniteweb.com> Message-ID: <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com> Thanks everyone for the good information! I?ve updated the functions to reflect return account_balance, but when I run other transactions the balance still defaults to original $500.25 I realize this isn?t the best exercise, the course only wanted us to define the functions and then use them, it did not include a loop or return. Just trying to figure out for my own curiosity. def balance(account_balance): # Define balance function print("Your current balance is $%.2f" % (account_balance)) # Prints the current avalible balance def deposit(account_balance, deposit_amount): # Define DEPOSIT function with parameters account_balance and deposit_amount deposit_amount = float(input("How much would you like to deposit today?\n")) # Accept user input for the deposit amount, in float format account_balance += deposit_amount # This addition assigns the updated value of the account blance, to the variable 'account_balance' print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, account_balance)) # Prints depost amount and account balance return account_balance # Return records the new value of account_balance to reflect accordingly in other transactions def withdrawal(account_balance, withdrawal_amount): # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount withdrawal_amount = float(input("How much would you like to withdraw today?\n")) # Accept user input for the withdrawal amount, in float format if withdrawal_amount > account_balance: # Checking to see if the amount requested, is greater than the amount avalible print("Insuffient funds, $%.2f is greater than your account balance of $%.2f" % (withdrawal_amount, account_balance)) # If the amount requested is greater than the account balance, there are insuffient funds else: # Suffient amount of funds are avalible, the function continues account_balance -= withdrawal_amount # Variable 'account_balance' is assigned to reflect the new avalible balance print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (withdrawal_amount, account_balance)) # Prints withdrawal amount and account balance return account_balance # Return records the new value of account_balance to reflect accordingly in other transactions Warm Regards, Mary Knauth 954-412-9280 maryknauth at mac.com http://www.zephyrsolutions.us > On Jun 20, 2020, at 11:23, alexkleider wrote: > > > ??????? Original Message ??????? > On Saturday, June 20, 2020 6:08 AM, Mary Knauth via Tutor wrote: > >> >> ?return account_balance = account_balance + deposit_amount? is an invalid syntax, so I need to read more about how to utilize return. > > Try > account_balance += deposit_amount > return account_balance > or simply > return account_balance + deposit_amount > From alan.gauld at yahoo.co.uk Sat Jun 20 13:57:14 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 20 Jun 2020 18:57:14 +0100 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com> References: <20200619234727.GO7425@apple.graniteweb.com> <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com> Message-ID: On 20/06/2020 18:22, Mary Knauth via Tutor wrote: > I?ve updated the functions to reflect return account_balance,> but when I run other transactions the balance still defaults to original $500.25 I suspect that's because you are not assigning the returned value. It is not enough to return the value you have to use it in your calling code. Although your parameter has the same name as the variable in your main code that is purely coincidental. The parameter inside the function has no impact on the variable outside. You need to assign the function return value to the variable. account_balance = 500.00 amount = float(input("How much to deposit?")) account_balance = deposit(account_balance, amount) # assign new balance print(account_balance) # should now be 500+amount > def deposit(account_balance, deposit_amount): > deposit_amount = float(input("How much would you like to deposit today?\n")) > account_balance += deposit_amount > print("Deposit was $%.2f , your new current balance is $%.2f" % (deposit_amount, account_balance)) > return account_balance Incidentally, it's considered best practice to avoid putting calculations and input/output statements in the same function. That's because it limits the ability to use the function in an application that uses a different type of display - like a web app, or GUI, say. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/l2p2 http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From david at graniteweb.com Sat Jun 20 15:24:17 2020 From: david at graniteweb.com (David Rock) Date: Sat, 20 Jun 2020 14:24:17 -0500 Subject: [Tutor] [maryknauth@mac.com: Re: Input parameters for functions] In-Reply-To: References: <20200619234727.GO7425@apple.graniteweb.com> <5E00FC2F-4CF0-4D48-A08A-2274BA6C9774@mac.com> Message-ID: <20200620192417.GS7425@apple.graniteweb.com> * Alan Gauld via Tutor [2020-06-20 18:57]: > On 20/06/2020 18:22, Mary Knauth via Tutor wrote: > > account_balance = 500.00 > amount = float(input("How much to deposit?")) > account_balance = deposit(account_balance, amount) # assign new balance > print(account_balance) # should now be 500+amount To stick with the functions you have already written, print(account_balance) could (should?) be replaced by balance(account_balance) As mentioned by others, the naming of that function is a little clunky. Changing to print_balance() would be a little clearer what it actually does (and explains why you would use it rather than just a simple print statement). -- David Rock david at graniteweb.com From robertvstepp at gmail.com Sun Jun 21 15:34:25 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 21 Jun 2020 14:34:25 -0500 Subject: [Tutor] How to find all current instances of a class? Message-ID: I had (perhaps) naively hoped that classes had dunder methods to list all current instances associated with that class, but if there is something that simple I have yet to find it. Does an easy, built-in method exist to list all current instances of a particular class? -- boB From mats at wichmann.us Sun Jun 21 15:46:39 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 21 Jun 2020 13:46:39 -0600 Subject: [Tutor] How to find all current instances of a class? In-Reply-To: References: Message-ID: <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us> On 6/21/20 1:34 PM, boB Stepp wrote: > I had (perhaps) naively hoped that classes had dunder methods to list > all current instances associated with that class, but if there is > something that simple I have yet to find it. Does an easy, built-in > method exist to list all current instances of a particular class? Python doesn't track this, so you gotta do it yourself. Two thoughts: (1) find all the objects - the garbage collector knows this - and filter that. (2) have the class track it - you can make a class attribute and add a weak reference to it each time the class initializer is called. Or (3) some other way I didn't think of (pretty much guaranteed to exist) For the former, I *think* this will be good enough, it's off the top of my head and so untested: import gc instances = [obj for obj in gc.get_objects() if isinstance(obj, ClassWeWantToTrack)] From alan.gauld at yahoo.co.uk Sun Jun 21 17:42:28 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 21 Jun 2020 22:42:28 +0100 Subject: [Tutor] How to find all current instances of a class? In-Reply-To: References: Message-ID: On 21/06/2020 20:34, boB Stepp wrote: > I had (perhaps) naively hoped that classes had dunder methods to list > all current instances associated with that class, but if there is > something that simple I have yet to find it. Does an easy, built-in > method exist to list all current instances of a particular class? Further to Mats' answer, I don't know any object system that does this, not even Smalltalk or CLOS.(The two most complete OOP systems around) After all there can be many millions of instances - think about strings and integers.... Tracking each instance of those would be a lot of work. But the "normal" way to do it if you need that facility is to create a classmethod/attribute that holds a list of instances. (Possibly by overriding __new__ or __init__). In fact this is often cited as an example of a class method(as opposed to an instance method. This is often associated with classes whose instances are persisted in a database. So you want to know if a particular instance is "in memory" or still in storage. You then access the instance appropriately. But Mat's idea of using the garbage collector is a neat trick. I'd never have thought of that one. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Sun Jun 21 19:21:30 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 21 Jun 2020 17:21:30 -0600 Subject: [Tutor] How to find all current instances of a class? In-Reply-To: References: Message-ID: <63817ee0-5a40-3a9f-c0f0-c01ba0ee0d73@wichmann.us> On 6/21/20 3:42 PM, Alan Gauld via Tutor wrote: > But Mat's idea of using the garbage collector is a neat trick. > I'd never have thought of that one. I read that idea somewhere once quite a while ago, not really taking personal credit :) From robertvstepp at gmail.com Sun Jun 21 19:41:02 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 21 Jun 2020 18:41:02 -0500 Subject: [Tutor] How to find all current instances of a class? In-Reply-To: <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us> References: <1ce09e03-a6e0-bb97-0260-29bf1923bd15@wichmann.us> Message-ID: On Sun, Jun 21, 2020 at 2:47 PM Mats Wichmann wrote: > > On 6/21/20 1:34 PM, boB Stepp wrote: > > I had (perhaps) naively hoped that classes had dunder methods to list > > all current instances associated with that class, but if there is > > something that simple I have yet to find it. Does an easy, built-in > > method exist to list all current instances of a particular class? > > Python doesn't track this, so you gotta do it yourself. > For the former, I *think* this will be good enough, it's off the top of > my head and so untested: > > import gc > > instances = [obj for obj in gc.get_objects() if isinstance(obj, > ClassWeWantToTrack)] Thanks, Mats, that does the trick quite nicely. My interest in this stems from exploring all the *hidden* information that is available about classes and their instances. After seeing all of the available information it struck me that I had not seen anything tracking instances. But what you and Alan say makes sense -- may be many such instances which would take unnecessary additional resources to track. -- boB From robertvstepp at gmail.com Sun Jun 21 22:35:11 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 21 Jun 2020 21:35:11 -0500 Subject: [Tutor] Counting objects: method vs. staticmethod vs. classmethod Message-ID: What I want to do: Every time I instantiate an object of a particular class I wish to generate a unique id dependent on a particular attribute value and the current number of objects created with that attribute value. Playing around tonight I have come up with the same technique expressed slightly differently. Which is best for what I want to do? Is there a better way to do what I want to do? 3.7.5: import random 3.7.5: from collections import Counter 3.7.5: import string 3.7.5: items = list(string.ascii_uppercase) 3.7.5: def make_objs(n, items, cls): ... for i in range(n): ... obj = cls(random.choice(items)) ... 3.7.5: class A: ... c = Counter() ... def count(item): ... A.c.update([item]) ... def __init__(self, item): ... A.count(item) ... 3.7.5: make_objs(1000, items, A) 3.7.5: A.c Counter({'U': 49, 'J': 47, 'Q': 47, 'A': 45, 'X': 45, 'Z': 44, 'S': 43, 'D': 42, 'T': 41, 'F': 41, 'O': 41, 'E': 40, 'Y': 38, 'W': 37, 'K': 37, 'H': 37, 'G': 37, 'N': 36, 'M': 35, 'B': 34, 'C': 33, 'R': 33, 'V': 32, 'I': 32, 'L': 29, 'P': 25}) 3.7.5: sum(A.c.values()) 1000 3.7.5: class B: ... c = Counter() ... @staticmethod ... def count(item): ... B.c.update([item]) ... def __init__(self, item): ... B.count(item) ... 3.7.5: make_objs(1000, items, B) 3.7.5: B.c Counter({'O': 52, 'X': 51, 'M': 50, 'G': 49, 'A': 49, 'P': 46, 'I': 45, 'H': 43, 'Z': 42, 'J': 42, 'L': 42, 'Q': 42, 'F': 41, 'D': 37, 'E': 37, 'N': 36, 'S': 33, 'C': 32, 'K': 32, 'R': 31, 'U': 31, 'W': 31, 'V': 30, 'T': 26, 'Y': 26, 'B': 24}) 3.7.5: class C: ... c = Counter() ... @classmethod ... def count(cls, item): ... C.c.update([item]) ... def __init__(self, item): ... C.count(item) ... 3.7.5: make_objs(1000, items, C) 3.7.5: C.c Counter({'R': 45, 'C': 45, 'Y': 44, 'A': 44, 'B': 44, 'K': 43, 'X': 43, 'E': 43, 'H': 42, 'P': 41, 'S': 41, 'Q': 41, 'L': 38, 'F': 38, 'I': 38, 'M': 37, 'U': 37, 'J': 37, 'O': 36, 'W': 35, 'G': 34, 'T': 34, 'V': 31, 'D': 31, 'Z': 30, 'N': 28}) The final counts are immaterial. I would use the value of c at the time of instantiation to generate its id attribute. The id would be used for __str__() to generate something like: "R22 MyObjectName". -- boB From alan.gauld at yahoo.co.uk Mon Jun 22 05:32:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 22 Jun 2020 10:32:49 +0100 Subject: [Tutor] Counting objects: method vs. staticmethod vs. classmethod In-Reply-To: References: Message-ID: On 22/06/2020 03:35, boB Stepp wrote: > What I want to do: Every time I instantiate an object of a particular > class I wish to generate a unique id dependent on a particular > attribute value and the current number of objects created with that > attribute value. Playing around tonight I have come up with the same > technique expressed slightly differently. Which is best for what I > want to do? Is there a better way to do what I want to do? They all can work, its mostly down to semantics. global functions are notionally for working with objects of any type. class methods are for working with the instances of a particular class, static methods are, IMHO, a fudge that I never use! So semantically, if you want to apply the function to multiple classes - or all then make it a global function. (In fact you may really want to look into tinkering with the metaclass mechanism!!) You might also consider adding a call to the fuction from the __init__() methods of the relevant classes. But if its a single class, or a class hierarchy, then make it a class method. (If its a few unrelated classes you could also make it a class method of a mixin class which you then inherit into all of the target classes.) In practice it won't make much difference but in terms of expressing intent it is probably bet to locate it where the purpose suggests. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Mon Jun 22 10:46:21 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 22 Jun 2020 16:46:21 +0200 Subject: [Tutor] Counting objects: method vs. staticmethod vs. classmethod References: Message-ID: boB Stepp wrote: > What I want to do: Every time I instantiate an object of a particular > class I wish to generate a unique id dependent on a particular > attribute value and the current number of objects created with that > attribute value. Playing around tonight I have come up with the same > technique expressed slightly differently. Which is best for what I > want to do? Is there a better way to do what I want to do? > > 3.7.5: import random > 3.7.5: from collections import Counter > 3.7.5: import string > 3.7.5: items = list(string.ascii_uppercase) > 3.7.5: def make_objs(n, items, cls): > ... for i in range(n): > ... obj = cls(random.choice(items)) > ... > 3.7.5: class A: > ... c = Counter() > ... def count(item): > ... A.c.update([item]) > ... def __init__(self, item): > ... A.count(item) > ... > 3.7.5: make_objs(1000, items, A) > 3.7.5: A.c > Counter({'U': 49, 'J': 47, 'Q': 47, 'A': 45, 'X': 45, 'Z': 44, 'S': > 43, 'D': 42, 'T': 41, 'F': 41, 'O': 41, 'E': 40, 'Y': 38, 'W': 37, > 'K': 37, 'H': 37, 'G': 37, 'N': 36, 'M': 35, 'B': 34, 'C': 33, 'R': > 33, 'V': 32, 'I': 32, 'L': 29, 'P': 25}) > 3.7.5: sum(A.c.values()) > 1000 > 3.7.5: class B: > ... c = Counter() > ... @staticmethod > ... def count(item): > ... B.c.update([item]) > ... def __init__(self, item): > ... B.count(item) > ... > 3.7.5: make_objs(1000, items, B) > 3.7.5: B.c > Counter({'O': 52, 'X': 51, 'M': 50, 'G': 49, 'A': 49, 'P': 46, 'I': > 45, 'H': 43, 'Z': 42, 'J': 42, 'L': 42, 'Q': 42, 'F': 41, 'D': 37, > 'E': 37, 'N': 36, 'S': 33, 'C': 32, 'K': 32, 'R': 31, 'U': 31, 'W': > 31, 'V': 30, 'T': 26, 'Y': 26, 'B': 24}) > 3.7.5: class C: > ... c = Counter() > ... @classmethod > ... def count(cls, item): > ... C.c.update([item]) > ... def __init__(self, item): > ... C.count(item) > ... > 3.7.5: make_objs(1000, items, C) > 3.7.5: C.c > Counter({'R': 45, 'C': 45, 'Y': 44, 'A': 44, 'B': 44, 'K': 43, 'X': > 43, 'E': 43, 'H': 42, 'P': 41, 'S': 41, 'Q': 41, 'L': 38, 'F': 38, > 'I': 38, 'M': 37, 'U': 37, 'J': 37, 'O': 36, 'W': 35, 'G': 34, 'T': > 34, 'V': 31, 'D': 31, 'Z': 30, 'N': 28}) > > The final counts are immaterial. I would use the value of c at the > time of instantiation to generate its id attribute. The id would be > used for __str__() to generate something like: "R22 MyObjectName". If you want to associate behaviour with a class that does not depend on the instance use static methods; if you want/expect that behaviour to change in subclasses use a class method. > ... @classmethod > ... def count(cls, item): > ... C.c.update([item]) That implementation defeats the purpose of class methods. >From within the class method access the class via the first argument: @classmethod def count(cls, item): cls.c.update([item]) That way you can tweak the code in subclassses. Likewise the initializer > ... def __init__(self, item): > ... C.count(item) becomes def __init__(self, item): self.count(item) A complete example based on the code you posted: $ cat classmethod_demo.py import random import string from collections import Counter class C: c = Counter() @classmethod def count(cls, item): cls.c.update([item]) def __init__(self, item): self.count(item) class D(C): c = Counter() classes = C, D for i in range(10): code = random.choice(string.ascii_uppercase) cls = random.choice(classes) obj = cls(code) for cls in classes: print("Created {} instances of {}:".format( sum(cls.c.values()), cls.__name__ )) print(cls.c) print() $ python3 classmethod_demo.py Created 4 instances of C: Counter({'M': 2, 'K': 1, 'Z': 1}) Created 6 instances of D: Counter({'J': 2, 'H': 1, 'D': 1, 'N': 1, 'I': 1}) From mats at wichmann.us Mon Jun 22 15:09:28 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 22 Jun 2020 13:09:28 -0600 Subject: [Tutor] Counting objects: method vs. staticmethod vs. classmethod In-Reply-To: References: Message-ID: On 6/21/20 8:35 PM, boB Stepp wrote: > What I want to do: Every time I instantiate an object of a particular > class I wish to generate a unique id dependent on a particular > attribute value and the current number of objects created with that > attribute value. Playing around tonight I have come up with the same > technique expressed slightly differently. Which is best for what I > want to do? Is there a better way to do what I want to do? > > 3.7.5: import random > 3.7.5: from collections import Counter by the way - bravo for using this "advanced" feature! :) From robertvstepp at gmail.com Tue Jun 23 08:58:36 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 23 Jun 2020 07:58:36 -0500 Subject: [Tutor] Testing classes with class variables: How best to reset class state between tests? Message-ID: class MyClass: class_var1 = value1 class_var2 = value2 ... methods some which may affect class variables This is a spinoff of my earlier questions about creating an instance counter for a class. I started to implement this in my actual code and started to write tests for the counter. I quickly realized that the counter variable retained state between tests, and, in fact, already written tests would now populate the counter before I ever got around to the new counter tests. So how to best deal with this? Two ideas come immediately to mind: 1) Use setup and/or teardown methods to manually reset all class variables to their desired initial state. A downside of this is that I will have to go back to all previous tests involving this class and add these methods. 2) Forcibly reloading the import with importlib.reload(myclassmodule). This seems like using a sledge hammer to swat a fly. And it would seem that it would have to be done repeatedly and added to earlier tests as well. Does Python provide a better solution? For the record my test runner is currently pytest. TIA! -- boB From __peter__ at web.de Wed Jun 24 02:53:45 2020 From: __peter__ at web.de (Peter Otten) Date: Wed, 24 Jun 2020 08:53:45 +0200 Subject: [Tutor] Testing classes with class variables: How best to reset class state between tests? References: Message-ID: boB Stepp wrote: > class MyClass: > class_var1 = value1 > class_var2 = value2 > ... > > methods some which may affect class variables > > This is a spinoff of my earlier questions about creating an instance > counter for a class. I started to implement this in my actual code > and started to write tests for the counter. I quickly realized that > the counter variable retained state between tests, and, in fact, > already written tests would now populate the counter before I ever got > around to the new counter tests. So how to best deal with this? Two > ideas come immediately to mind: > > 1) Use setup and/or teardown methods to manually reset all class > variables to their desired initial state. A downside of this is that > I will have to go back to all previous tests involving this class and > add these methods. setUp()/tearDown() seems fine. Put them into a base class that you can derive from to avoid repetition. > > 2) Forcibly reloading the import with importlib.reload(myclassmodule). > This seems like using a sledge hammer to swat a fly. And it would > seem that it would have to be done repeatedly and added to earlier > tests as well. That's a hack; you can never be sure that you have replaced all objects from the previous import. > Does Python provide a better solution? For the record my test runner > is currently pytest. While I think (1) is fine you may also consider pytest's autouse fixtures. From samuelearabia10 at gmail.com Wed Jun 24 16:45:04 2020 From: samuelearabia10 at gmail.com (Samuele) Date: Wed, 24 Jun 2020 22:45:04 +0200 Subject: [Tutor] I Have An Error OS: Windows 10 Python: 3.7 thanks for the help Message-ID: i start to learn kivy i do the first start but i have an error i have 2 files the code is below : the Kivy code is : : BoxLayout: id: main_box orientation: "vertical" the Python code is : from kivy.app import App from kivy.uix.boxlayout import BoxLayout class MainWindow(BoxLayout): pass class MainApp(App): def build(self): return MainWindow() sample_app = MainApp() sample_app.run() this is the error : [INFO ] [Logger ] Record log in C:\Users\marti\.kivy\logs\kivy_20-06-24_26.txt [INFO ] [Kivy ] v1.11.1 [INFO ] [Kivy ] Installed at "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\__init__.py" [INFO ] [Python ] v3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] [INFO ] [Python ] Interpreter at "C:\Users\marti\PycharmProjects\Project [Atom]\venv\Scripts\python.exe" [INFO ] [Factory ] 184 symbols loaded [INFO ] [Image ] Providers: img_tex, img_dds, img_gif (img_sdl2, img_pil, img_ffpyplayer ignored) Traceback (most recent call last): File "C:/Users/marti/PycharmProjects/Test Kivy/main.py", line 15, in sample_app.run() File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\app.py", line 828, in run self.load_kv(filename=self.kv_file) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\app.py", line 599, in load_kv root = Builder.load_file(rfilename) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file return self.load_string(data, **kwargs) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 368, in load_string parser = Parser(content=string, filename=fn) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 401, in __init__ self.parse(content) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 510, in parse objects, remaining_lines = self.parse_level(0, lines) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 614, in parse_level level + 1, lines[i:], spaces) File "C:\Users\marti\PycharmProjects\Project [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 673, in parse_level if current_property[:3] == 'on_': TypeError: 'NoneType' object is not subscriptable Process finished with exit code 1 From alan.gauld at yahoo.co.uk Wed Jun 24 16:56:50 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 24 Jun 2020 21:56:50 +0100 Subject: [Tutor] I Have An Error OS: Windows 10 Python: 3.7 thanks for the help In-Reply-To: References: Message-ID: On 24/06/2020 21:45, Samuele wrote: > i start to learn kivy i do the first start but i have an error > i have 2 files the code is below : Since there is almost no Python there it is hard to see what the error might be unless you know kivy. This is really a kivy issue and you will probably get a better response asking on the kivy forum. https://kivy.org/#forum HTH, Alan G. > > the Kivy code is : > > : > BoxLayout: > id: main_box > orientation: "vertical" > > > the Python code is : > > from kivy.app import App > from kivy.uix.boxlayout import BoxLayout > > > class MainWindow(BoxLayout): > pass > > > class MainApp(App): > def build(self): > return MainWindow() > > > sample_app = MainApp() > sample_app.run() > > > > > > this is the error : > [INFO ] [Logger ] Record log in > C:\Users\marti\.kivy\logs\kivy_20-06-24_26.txt > [INFO ] [Kivy ] v1.11.1 > [INFO ] [Kivy ] Installed at > "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\__init__.py" > [INFO ] [Python ] v3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) > [MSC v.1914 64 bit (AMD64)] > [INFO ] [Python ] Interpreter at > "C:\Users\marti\PycharmProjects\Project [Atom]\venv\Scripts\python.exe" > [INFO ] [Factory ] 184 symbols loaded > [INFO ] [Image ] Providers: img_tex, img_dds, img_gif (img_sdl2, > img_pil, img_ffpyplayer ignored) > Traceback (most recent call last): > File "C:/Users/marti/PycharmProjects/Test Kivy/main.py", line 15, in > > sample_app.run() > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\app.py", line 828, in run > self.load_kv(filename=self.kv_file) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\app.py", line 599, in load_kv > root = Builder.load_file(rfilename) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file > return self.load_string(data, **kwargs) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\builder.py", line 368, in > load_string > parser = Parser(content=string, filename=fn) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 401, in __init__ > self.parse(content) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 510, in parse > objects, remaining_lines = self.parse_level(0, lines) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 614, in parse_level > level + 1, lines[i:], spaces) > File "C:\Users\marti\PycharmProjects\Project > [Atom]\venv\lib\site-packages\kivy\lang\parser.py", line 673, in parse_level > if current_property[:3] == 'on_': > TypeError: 'NoneType' object is not subscriptable > > Process finished with exit code 1 > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From savageapple850 at gmail.com Thu Jun 25 10:56:12 2020 From: savageapple850 at gmail.com (Cravan) Date: Thu, 25 Jun 2020 22:56:12 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' Message-ID: Hi all, ??????????????? I recently embarked on learning Q-learning in python, but got an error that I?ve no idea how to fix. So here?s my code in one of my .py files: ``` class Zomb(pg.sprite.Sprite): ??? def __init__(self, game, m, n): ??????? self.groups = game.all_sprites, game.zombs ??????? pg.sprite.Sprite.__init__(self, self.groups) ??????? self.game = game ??????? self.image = game.zomb_img ??????? self.rect = self.image.get_rect() ??????? self.pos = vec(m, n) * TILESIZE ??????? self.m = m ??????? self.n = n ??????? #self.pos.x will return the x-coordinate in the grid world ??????? self.stateSpace = [i for i in range(int(GRIDWIDTH) * int(GRIDHEIGHT))] ??????? self.actionSpace = {'U': vec(0, -self.m), 'D': vec(0, self.m), ??????????????????????????? 'L': vec(-1,0), 'R': vec(1,0)} ??????? self.possibleActions = ['U', 'D', 'L', 'R'] ??????? self.vel = vec(0, 0) ??????? self.acc = vec(0, 0) ??????? self.rect.center = self.pos ??????? self.rotate = 0 ???def setState(self, state): ??????? self.pos = state ??? def TerminalState(self, state): ??????? if self.game.health == 0: ??????????? return True ??????? else: ??????????? return False ??? def step(self, action): ??????? x, y = self.pos.x, self.pos.y ??????? resultingState = self.pos + self.actionSpace[action] ??????? self.game.reward = -1 if not self.TerminalState(resultingState) else 0 ??????? self.setState(resultingState) ??????? return resultingState,self.game.reward,\ ??????????? self.TerminalState(resultingState), None ??? def actionSpaceSample(self): ??????? return np.random.choice(self.possibleActions) ??? def update(self): ??????? self.image = game.zomb_img ??????? self.rect = self.image.get_rect() ????? ??self.rect.center = self.pos ??????? self.acc = vec(ZOMB_SPEED, 0) ??????? self.acc += self.vel * -1 ??????? self.vel += self.acc * self.game.dt ??????? self.pos += self.vel * self.game.dt + 0.5 * self.acc * self.game.dt ** 2 ??????? print(self.pos) ``` And here?s the processing part in my main .py file: ````` g = Game() def maxAction(Q, state, actions): ??? values = np.array([Q[state,a] for a in actions]) ??? action = np.argmax(values) ??? return actions[action] while True: ??? g.new() ??? ALPHA = 0.1 ??? GAMMA = 1.0 ??? EPS = 1.0 ??? Q = {} ??? for zomb in g.zombs: ??????? for state in zomb.stateSpace: ??????????? for action in zomb.possibleActions: ??????????????? Q[state, action] = 0 ??? numGames = 10 ??? totalRewards = np.zeros(numGames) ??? for i in range(numGames): ??????? print('starting game ', i) ??????? done = False ??????? g.new() ??????? epRewards = 0 ??? while not done: ??????? rand = np.random.random() ??????? for zomb in g.zombs: ??????????? observation = zomb.pos ??????????? action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \ ??????????????????????????????????????????????????????? else zomb.actionSpaceSample() ??????????? observationnew, reward, done, info = zomb.step(action) ??????? epRewards += reward ??????? for zomb in g.zombs: ??????????? possible_actions = zomb.possibleActions ??????????? action = maxAction(Q, observationnew, possible_actions) ??????? Q[observation,action] = Q[observation,action] + ALPHA*(reward + \ ??????????????????? GAMMA*Q[observationnew,action_] - Q[observation,action]) ??????? observation = observationnew ??????? if EPS - 2 / numGames > 0: ??????????? EPS -= 2 / numGames ??????? else: ??????????? EPS = 0 ??????? totalRewards[i] = epRewards g.run() ```` However when I run the second file I encounter an error: Traceback (most recent call last): ? File "maze.py", line 170, in ??? action = maxAction(Q, observationnew, possible_actions) ? File "maze.py", line 136, in maxAction ??? values = np.array([Q[state,a] for a in actions]) ? File "maze.py", line 136, in ??? values = np.array([Q[state,a] for a in actions]) TypeError: unhashable type: 'pygame.math.Vector2' From savageapple850 at gmail.com Thu Jun 25 11:05:30 2020 From: savageapple850 at gmail.com (Cravan) Date: Thu, 25 Jun 2020 23:05:30 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' Message-ID: Hi all, ??????????????? I recently began learning Q-learning in Python but encountered an error. Here?s my code for the Agent in one of my .py files: ```` class Zomb(pg.sprite.Sprite): ??? def __init__(self, game, m, n): ??????? self.groups = game.all_sprites, game.zombs ??????? pg.sprite.Sprite.__init__(self, self.groups) ??????? self.game = game ??????? self.image = game.zomb_img ??????? self.rect = self.image.get_rect() ??????? self.pos = vec(m, n) * TILESIZE ??????? self.m = m ??????? self.n = n ??????? #self.pos.x will return the x-coordinate in the grid world ??????? self.stateSpace = [i for i in range(int(GRIDWIDTH) * int(GRIDHEIGHT))] ??????? self.actionSpace = {'U': vec(0, -self.m), 'D': vec(0, self.m), ??????????????????????????? 'L': vec(-1,0), 'R': vec(1,0)} ??????? self.possibleActions = ['U', 'D', 'L', 'R'] ??????? self.vel = vec(0, 0) ??????? self.acc = vec(0, 0) ??????? self.rect.center = self.pos ??????? self.rotate = 0 ??? def setState(self, state): ??????? self.pos = state ??? def TerminalState(self, state): ??????? if self.game.health == 0: ??????????? return True ??????? else: ??????????? return False ??? def step(self, action): ??????? x, y = self.pos.x, self.pos.y ??????? resultingState = self.pos + self.actionSpace[action] ??????? self.game.reward = -1 if not self.TerminalState(resultingState) else 0 ??????? self.setState(resultingState) ??????? return resultingState,self.game.reward,\ ??????????? self.TerminalState(resultingState), None ??? def actionSpaceSample(self): ??????? return np.random.choice(self.possibleActions) ??? def update(self): ??????? self.image = game.zomb_img ??????? self.rect = self.image.get_rect() ??????? self.rect.center = self.pos ??????? self.acc = vec(ZOMB_SPEED, 0) ??????? self.acc += self.vel * -1 ??????? self.vel += self.acc * self.game.dt ??????? self.pos += self.vel * self.game.dt + 0.5 * self.acc * self.game.dt ** 2 ??????? print(self.pos) ```` And here?s the processing and implementation of Q-learning in my main code: ```` g = Game() def maxAction(Q, state, actions): ??? values = np.array([Q[state,a] for a in actions]) ??? action = np.argmax(values) ??? return actions[action] while True: ??? g.new() ??? ALPHA = 0.1 ??? GAMMA = 1.0 ??? EPS = 1.0 ??? Q = {} ??? for zomb in g.zombs: ??????? for state in zomb.stateSpace: ??????????? for action in zomb.possibleActions: ??????????????? Q[state, action] = 0 ??? numGames = 10 ??? totalRewards = np.zeros(numGames) ??? for i in range(numGames): ??????? print('starting game ', i) ??????? done = False ??????? g.new() ??????? epRewards = 0 ??? while not done: ??????? rand = np.random.random() ??????? for zomb in g.zombs: ??????????? observation = zomb.pos ??????????? action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \ ???????????????????????????????????????????????????????else zomb.actionSpaceSample() ??????????? observationnew, reward, done, info = zomb.step(action) ??????? epRewards += reward ??????? for zomb in g.zombs: ??????????? possible_actions = zomb.possibleActions ??????????? action = maxAction(Q, observationnew, possible_actions) ??????? Q[observation,action] = Q[observation,action] + ALPHA*(reward + \ ??????????????????? GAMMA*Q[observationnew,action_] - Q[observation,action]) ??????? observation = observationnew ??????? if EPS - 2 / numGames > 0: ??????????? EPS -= 2 / numGames ??????? else: ??????????? EPS = 0 ??????? totalRewards[i] = epRewards g.run() ```` However, this error popped out: ###### Traceback (most recent call last): ? File "maze.py", line 170, in ??? action = maxAction(Q, observationnew, possible_actions) ? File "maze.py", line 136, in maxAction ??? values = np.array([Q[state,a] for a in actions]) ? File "maze.py", line 136, in ??? values = np.array([Q[state,a] for a in actions]) TypeError: unhashable type: 'pygame.math.Vector2' ###### Could someone provide me with a way to rectify this problem? (removing the vector sign in the dictionary doesn?t seem to help, another error pops up). Thanks, Cravan P.S. Also erm I made a buncha mistakes along the way, would appreciate any suggestion or help. Thanks! From mats at wichmann.us Thu Jun 25 11:20:42 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 25 Jun 2020 09:20:42 -0600 Subject: [Tutor] Testing classes with class variables: How best to reset class state between tests? In-Reply-To: References: Message-ID: On 6/24/20 12:53 AM, Peter Otten wrote: > boB Stepp wrote: > >> class MyClass: >> class_var1 = value1 >> class_var2 = value2 >> ... >> >> methods some which may affect class variables >> >> This is a spinoff of my earlier questions about creating an instance >> counter for a class. I started to implement this in my actual code >> and started to write tests for the counter. I quickly realized that >> the counter variable retained state between tests, and, in fact, >> already written tests would now populate the counter before I ever got >> around to the new counter tests. So how to best deal with this? Two >> ideas come immediately to mind: >> >> 1) Use setup and/or teardown methods to manually reset all class >> variables to their desired initial state. A downside of this is that >> I will have to go back to all previous tests involving this class and >> add these methods. > > setUp()/tearDown() seems fine. Put them into a base class that you can > derive from to avoid repetition. the concept of setup and teardown in testing is pretty fundamental, without it tests which affect state will cause your overall test run to be a mess, so you shouldn't be uncomfortable with it. autouse seems to be pytest's way to go a bit beyond the "classic {x}Unit way" and make things a bit more usable. I had to look it up, was new to me :) See, we all learn something from these interactions! This example seems to fit your case fairly well: https://docs.pytest.org/en/stable/fixture.html#autouse-fixtures From mats at wichmann.us Thu Jun 25 12:06:04 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 25 Jun 2020 10:06:04 -0600 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: References: Message-ID: On 6/25/20 8:56 AM, Cravan wrote: > Hi all, > > ??????????????? I recently embarked on learning Q-learning in python, but got an error that I?ve no idea how to fix. So here?s my code in one of my .py files: > However when I run the second file I encounter an error: > > Traceback (most recent call last): > ? File "maze.py", line 170, in > ??? action = maxAction(Q, observationnew, possible_actions) > ? File "maze.py", line 136, in maxAction > ??? values = np.array([Q[state,a] for a in actions]) > ? File "maze.py", line 136, in > ??? values = np.array([Q[state,a] for a in actions]) > TypeError: unhashable type: 'pygame.math.Vector2' a TypeError generically means you are using an incompatible data type in place which has a restriction on what types can be used. Your Q is a dictionary; Q = {} and dicts specifically have the restriction that the type be hashable (meaning it must be a type that doesn't change during runtime, like a list - or a 2d Vector in your case), because when a key is inserted into the dict, Python stores the hash of it for later lookups, and if, later, it would hash differently because it has changed, the lookup wouldn't work. the "state" you pass to maxAction, where the error was raised, looks like it's probably a vector since it sounds like it represents a position: observation = zomb.pos action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \ else zomb.actionSpaceSample() if zomb.pos was indeed a Vector2, then indexing Q using that as part of the (state, a) tuple is the cause of your problem. Are you sure it's a position you wanted to pass in this call? values = np.array([Q[state,a] for a in actions]) From mats at wichmann.us Thu Jun 25 12:17:52 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 25 Jun 2020 10:17:52 -0600 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: References: Message-ID: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> On 6/25/20 10:06 AM, Mats Wichmann wrote: sigh... think one thing, write another: > Your Q is a dictionary; > > Q = {} > > and dicts specifically have the restriction that the type be hashable ... that the _key_ be hashable ... From savageapple850 at gmail.com Thu Jun 25 19:40:00 2020 From: savageapple850 at gmail.com (Cravan) Date: Fri, 26 Jun 2020 07:40:00 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> Message-ID: <72714CDD-59CB-4F90-85A7-15EDA3F13449@gmail.com> Hmm, I think I'll reconsider the use of vectors altogether. Thanks Mats! Appreciate your quick response! Cheers, Cravan > On 6/25/20 10:06 AM, Mats Wichmann wrote: > sigh... think one thing, write another: > Your Q is a dictionary; > > Q = {} > > and dicts specifically have the restriction that the type be hashable ... that the _key_ be hashable ... _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From PyTutor at DancesWithMice.info Thu Jun 25 21:50:26 2020 From: PyTutor at DancesWithMice.info (DL Neil) Date: Fri, 26 Jun 2020 13:50:26 +1200 Subject: [Tutor] Review: Good Habits for Great Coding Message-ID: Good Habits for Great Coding : Improving Programming Skills with Examples in Python, Michael Stueben, Apress, 2018 My disappointment with this book is largely a consequence of my own expectations. The title raised hopes that it would improve my own coding efforts, or that it would offer teaching techniques which might improve my approach to training in IT. The first indication of a poor 'fit' was its dedication "to the isolated CS teacher and student". Sadly, many of the errors or examples of poor teaching would not have occurred, had the author been less 'isolated' and spent time interacting with the world-wide Python community! The Introduction reveals the author to be a victim of his environment. School math and 'toy examples' lead to the conclusion that short/algebra-like variable-identification is "efficient" and that 'pretty boxes' around module docstrings add value and improve 'looks'. Yet, the later chapter on "Self-Documenting Code" reverses such advice, instead preferring descriptively-meaningful names. Whilst it is not necessary for all code to adhere to PEP-8 standards, it is difficult to imagine why one would deliberately teach differently, eg re-defining indentation. Generally, C- and Java-esque techniques do not transfer to Python. For example, camel-case for variable or function names is frowned-upon, but such, and the likes of for...in range(...) constructs, appear with alarming frequency. In eschewing the generic 'in-joke' function names such as "foo", "bar", and "baz" (which few would ever use in practice anyway), the author instead promotes the no-less meaningful "doIt()" for general-purposes, purportedly following a verb-object name-form recommendation. Similarly, but contrary to the usual EAFP/'we're all adults' ethos of the Python world; in the book's programmer-as-user example exercises there is emphasis on "testing for any pre-condition and boundary condition". In that environment, using assert to 'prove' an input or a result might be acceptable, but in 'the real world' risking such a hard-stop (decorated by a user-alarming error message and trace-back) would not. Conversely, in the "Expert Advice" chapter we read that "Robust code...heals itself...crashes gracefully". A single, solitary use of the pythonic try...except structure can be recalled, but those keywords do not appear in the book's index. The 'batteries included' advantages of the Python Standard Library don't receive coverage. Indeed the author details 'utility code' to debug-print a matrix structure, whereas most of us would reach for the pprint library. Ironically, recalling the development of such code, gives occasion to introduce the concept of "YAGNI". Stueben concludes (rightly) that the problem with students not appreciating the need for style or readability is implicit within the traditional 'work by yourself, and for yourself' methods of schooling (this is changing); and how, to demand apparently-abstract adherence to standards or convention would create an apposite relationship between teacher and student. No doubt! Confirming this admission of defeat, the chapter on "Style" is sandwiched between two entitled, "Coding Tricks" and "More Coding Tricks". However, professionals would say that coding-style cannot be ignored. Accordingly most trainers attempt to model 'best-practice' in our training materials. Sadly, the reality is that a good docstring for a toy-example may be longer than the actual code. Thus, such ideals may actually interfere with the learning process. Exigencies apply! Therefore, one of the book's (and the class's) missed-opportunities is that professionals (and students) may only ever convince themselves of such a need, after 'suffering' through reading and maintaining/improving others' code - at which point we 'discover' the struggles of wading-through a 'tangled mess'. (Perhaps a message to all of us?) There is a useful chapter on Testing, followed by four weakly-justified pages on Defensive Programming. However, the TDD (and others) approach of separating code from test modules is not mentioned. Debug-prints are favored over debuggers. Scaffolding "which will be removed eventually" is recommended, despite the virtue of test-runners remaining available for future use. There is a nod towards Numerical Analysis in coverage of the 'dangers' inherent in floating-point computation, which many would be wise to absorb! Unfortunately, this content will not encourage or extend your experience into Python's Decimal library. The math-bias shows in the strength of algorithmic coverage, and the dearth of data considerations. Even Data Scientists preface their analyses with data-collection, and data-cleaning processes! Within an environment concentrating on implementing algorithms with simple (and tailored) data formats, such a view may be justifiable. Object-Oriented Programming receives short-shrift, which is likely appropriate, given the examples' subject-matter, and the lack of (need for, teaching-approach using) re-use. Sadly, in a discussion of the 'Traveling Salesman Problem' he recommends a complex structure of mutable lists for x,y co-ordinates to which id-s (pointers) are added. Whereas, a custom class would simplify understanding and better relieve the loss of "control" (of the code-solution) he describes. Some will support the chapter "Beware of OOP", whilst others recoil in horror. Again, a divergence between ComSc and industry, and a predilection for edge-cases seem to justify the author's views. The many advantages built-in to popular Python IDEs are also a missed opportunity. Likewise, GUI and web interfaces are not discussed. That said, time is devoted to building speed-tests as means of refinement and an aid to refactoring. To be fair, it is not easy to convince high school students, or for that matter many neophyte programmers, of the virtues of 'industry standards', eg avoiding 'clever code' to enhance readability. Which implies that the title of the book is too general and requires a more descriptive (and accurate) sub-title, eg "for High School Computing". Further, to be true to the comparisons drawn in "Expert Advice", the book's sub-title should replace its current "Programming Skills" with the term "Computer Science", thus justifying the author's view that "professional software developers work in a significantly different world from the C.S. student. ...team...legacy code...end users...convenient interfaces...consistency" contrasting radically with "code up algorithms that will be run one time in front of the teacher". This book's title is a publisher's marketing-masterpiece of community appeal. However, the content fails to deliver on the promise. If you seek advice about professional practice, or to improve Python skills, look elsewhere. If you are a High School student considering IT as a career, look elsewhere. However, if you are a math-based, ComSc student (including, perhaps, first-year University Under-Graduates) and you're studying algorithms, this book includes much food-for-thought. The reviewer's first degree included a ComSc major. He has worked in IT and business for decades, and is an international consultant and vocational trainer. -- Regards, =dn From royskanti at gmail.com Thu Jun 25 23:46:15 2020 From: royskanti at gmail.com (SUMAN KANTI ROY) Date: Fri, 26 Jun 2020 09:16:15 +0530 Subject: [Tutor] column heading Message-ID: a=[1,2,3,4,5,6,7,8,9,10] arr=[[1,2],[2,23],[4,5]] dic={} for i in range(0,len(arr)): if arr[i][0] not in dic: dic[arr[i][0]]=arr[i][1] arr1=[] def find_key(val,dic): for i in dic.keys(): if dic[i]==val: return i new_arr=sorted(dic.values(),reverse=True) ans= [[0 for i in range(3)] for i in range(len(new_arr))] for i in range(len(new_arr)): ans[i][0]=a[i] ans[i][1]=find_key(new_arr[i],dic) ans[i][2]=new_arr[i] print(ans) 0/p=====[[1, 2, 23], [2, 4, 5], [3, 1, 2]] I want to make it 3 column matrix ,,,with column heading name['device',R.B.N','CQI'] please guide me... From alan.gauld at yahoo.co.uk Fri Jun 26 04:34:46 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 26 Jun 2020 09:34:46 +0100 Subject: [Tutor] column heading In-Reply-To: References: Message-ID: On 26/06/2020 04:46, SUMAN KANTI ROY wrote: > a=[1,2,3,4,5,6,7,8,9,10] > arr=[[1,2],[2,23],[4,5]] > dic={} > for i in range(0,len(arr)): > if arr[i][0] not in dic: > dic[arr[i][0]]=arr[i][1] Any time you see yourself writing code like this you should give yourself a hard slap! Its virtually never the right thing to do in Python. Even if you need the index you can use enumerate(). But usually you don't even need that. In this case you can use variable unpacking to write: for a,b in arr: if a not in dic: dic[a] = b Which is significantly easier to read, and debug. > arr1=[] > def find_key(val,dic): > for i in dic.keys(): > if dic[i]==val: > return i Similarly here, if you use dic.items instead of keys you can avoid indexing. for k,v in dic.items(): if val == v: return k > new_arr=sorted(dic.values(),reverse=True) ok... > ans= [[0 for i in range(3)] for i in range(len(new_arr))] > for i in range(len(new_arr)): > ans[i][0]=a[i] > ans[i][1]=find_key(new_arr[i],dic) > ans[i][2]=new_arr[i] ans = ['device, 'R B N', 'CQI'] for index,item in enumerate(new_arr): ans.append([ a[index], # probably a better way of doing this find_key(item,dic), item]) > I want to make it 3 column matrix ,,,with column heading > name['device',R.B.N','CQI'] Try to avoid using indexes they are error prone and hard to read or debug. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PyTutor at danceswithmice.info Fri Jun 26 05:33:19 2020 From: PyTutor at danceswithmice.info (dn) Date: Fri, 26 Jun 2020 21:33:19 +1200 Subject: [Tutor] column heading In-Reply-To: References: Message-ID: On 26/06/20 3:46 PM, SUMAN KANTI ROY wrote: > a=[1,2,3,4,5,6,7,8,9,10] > arr=[[1,2],[2,23],[4,5]] > dic={} > for i in range(0,len(arr)): > if arr[i][0] not in dic: > dic[arr[i][0]]=arr[i][1] > arr1=[] > def find_key(val,dic): > for i in dic.keys(): > if dic[i]==val: > return i > new_arr=sorted(dic.values(),reverse=True) > ans= [[0 for i in range(3)] for i in range(len(new_arr))] > for i in range(len(new_arr)): > ans[i][0]=a[i] > ans[i][1]=find_key(new_arr[i],dic) > ans[i][2]=new_arr[i] > print(ans) > > 0/p=====[[1, 2, 23], [2, 4, 5], [3, 1, 2]] > I want to make it 3 column matrix ,,,with column heading > name['device',R.B.N','CQI'] > please guide me... As @Alan has said, you are trying to write Java/C/? in Python. The Python language has its own idioms and techniques. I'm also going to criticise the choice of variable_names - and Python uses "lists" not "arrays"! Here is some food for thought (and there are other ways of achieving the same): - because the array is a list of 2-member lists you can use Python's dynamic conversions: >>> arr=[[1,2],[2,23],[4,5]] >>> dic = dict( arr ) >>> dic {1: 2, 2: 23, 4: 5} - each element of a dictionary consists of a key and a value. They can be considered separately: >>> keys = dic.keys() >>> keys dict_keys([1, 2, 4]) >>> values = dic.values() - two lists can be joined - except that the basic result is an iterator: >>> inverted_arr = list( zip( dic.values(), dic.keys() ) ) >>> inverted_arr [(2, 1), (23, 2), (5, 4)] - and just to complete the picture, we do the list-to-dict 'trick' again: >>> inverted_dic = dict( inverted_arr ) >>> inverted_dic {2: 1, 23: 2, 5: 4} - which has generated all of the constructs needed! I'll leave it to you to decide if you need the inverted dict. Research the Python documentation (it's very good!), and note that zip() allows multiple lists to be zip-ped together, providing... Can you now solve the problem without using any for-loops? -- Regards =dn From savageapple850 at gmail.com Fri Jun 26 10:25:32 2020 From: savageapple850 at gmail.com (Cravan) Date: Fri, 26 Jun 2020 22:25:32 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> Message-ID: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> Sadly, an error pops up when I change the code. Here's my edited code for the class file: ```` class Zomb(pg.sprite.Sprite): def __init__(self, game, x, y): self.groups = game.all_sprites, game.zombs pg.sprite.Sprite.__init__(self, self.groups) self.game = game self.image = game.zomb_img self.rect = self.image.get_rect() #image = image provided in game self.x = x self.y = y self.pos = (x, y) #this is each state #possible states for a in range(int(GRIDWIDTH)): for b in range(int(GRIDHEIGHT)): self.stateSpace = [(a,b)] self.actionSpace = {'U': - 1, 'D': 1, 'L': - 1, 'R': 1} #corresponding adjustments self.possibleActions = ['U', 'D', 'L', 'R'] #list of possible actions self.vel = 0 self.acc = 0 self.rect.center = vec(self.x, self.y) self.rotate = 0 def setState(self, state): self.pos = state def TerminalState(self, state): if self.game.health == 0: return True else: return False def step(self, action): x, y = self.x, self.y if self.actionSpace[action] == 'U': self.y = self.y + 1 elif self.actionSpace[action] == 'D': self.y = self.y - 1 elif self.actionSpace[action] == 'R': self.x = self.x + 1 elif self.actionSpace[action] == 'L': self.x = self.x - 1 resultingState = (self.x, self.y) self.game.reward = -1 if not self.TerminalState(resultingState) else 0 self.setState(resultingState) return resultingState, self.game.reward,\ self.TerminalState(resultingState), None def actionSpaceSample(self): return np.random.choice(self.possibleActions) def update(self): self.rotate = (self.game.player.pos - self.rect.center).angle_to(vec(1, 0)) self.image = self.game.zomb_img self.rect = self.image.get_rect() self.acc = vec(ZOMB_SPEED, 0).rotate(-self.rotate) ```` And here's my edited main implementation now in the update() function: ``` ALPHA = 0.1 GAMMA = 1.0 EPS = 1.0 Q = {} for zomb in self.zombs: print(zomb.stateSpace) for state in zomb.stateSpace: for action in zomb.possibleActions: Q[state, action] = 0 numGames = 10 totalRewards = np.zeros(numGames) for i in range(numGames): print('starting game ', i + 1) epRewards = 0 rand = np.random.random() for zomb in self.zombs: observation = zomb.pos #state action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \ else zomb.actionSpaceSample() #choosing the best action possible observationnew, reward, done, info = zomb.step(action) epRewards += reward for zomb in self.zombs: possible_actions = zomb.possibleActions action_ = maxAction(Q, observationnew, possible_actions) Q[observation,action] = Q[observation,action] + ALPHA*(reward + \ GAMMA*Q[observationnew,action_] - Q[observation,action]) observation = observationnew if EPS - 2 / numGames > 0: EPS -= 2 / numGames else: EPS = 0 totalRewards[i] = epRewards ``` However, this error pops up: ####### Traceback (most recent call last): File "maze.py", line 181, in g.run() File "maze.py", line 53, in run self.update() File "maze.py", line 109, in update action_ = maxAction(Q, observationnew, possible_actions) File "maze.py", line 177, in maxAction values = np.array([Q[state,a] for a in actions]) File "maze.py", line 177, in values = np.array([Q[state,a] for a in actions]) KeyError: ((6, 26), 'U') ###### Apologies for the (late) and long email here, would appreciate if someone could offer some help. Thanks, Cravan ?On 26/6/20, 12:18 AM, "Tutor on behalf of Mats Wichmann" wrote: On 6/25/20 10:06 AM, Mats Wichmann wrote: sigh... think one thing, write another: > Your Q is a dictionary; > > Q = {} > > and dicts specifically have the restriction that the type be hashable ... that the _key_ be hashable ... _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From john at johnweller.co.uk Fri Jun 26 06:21:02 2020 From: john at johnweller.co.uk (John Weller) Date: Fri, 26 Jun 2020 11:21:02 +0100 Subject: [Tutor] Running Python Scripts at same time Message-ID: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> I have a Python program which will be running 24/7 (I hope ?). It is generating data in a file which I want to clean up overnight. The way I am looking at doing it is to run a separate program as a Cron job at midnight ? will that work? The alternative is to add it to the loop and check for the time. I have tried researching this but only got even more confused. Thanks John John Weller 01380 723235 07976 393631 From alan.gauld at yahoo.co.uk Fri Jun 26 10:38:22 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 26 Jun 2020 15:38:22 +0100 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> Message-ID: On 26/06/2020 11:21, John Weller wrote: > I have a Python program which will be running 24/7 (I hope ?). > It is generating data in a file which I want to clean up overnight. > The way I am looking at doing it is to run a separate program > as a Cron job at midnight ? will that work? Yes, there is no limit to how many concurrent python sessions you run.(Apart from the capacity of your computer of courses) But it will be a completely separate program. It will have no access to the variables or state of your original program. You won't for example be able to tell whether the original program is writing to the file at the time you want to delete it. You will need to ensure that the code of each is robust enough to handle that. The usual way of dealing with that is to get the first program to write to a file whose name incorporates the date. Then it will automatically create a new file each day. Your second program can then do what it wishes with the previous days file, certain that the first won't be interfering with it. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Fri Jun 26 10:41:48 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 26 Jun 2020 08:41:48 -0600 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> Message-ID: <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us> On 6/26/20 8:25 AM, Cravan wrote: > Sadly, an error pops up when I change the code. > Here's my edited code for the class file: > However, this error pops up: > ####### > Traceback (most recent call last): > File "maze.py", line 181, in > g.run() > File "maze.py", line 53, in run > self.update() > File "maze.py", line 109, in update > action_ = maxAction(Q, observationnew, possible_actions) > File "maze.py", line 177, in maxAction > values = np.array([Q[state,a] for a in actions]) > File "maze.py", line 177, in > values = np.array([Q[state,a] for a in actions]) > KeyError: ((6, 26), 'U') > ###### > > Apologies for the (late) and long email here, would appreciate if someone could offer some help. Well, again the error tells you what is happening: KeyError means you tried to look up a key in a dictionary that is actually not present in the dictionary. So Q does not contain the tuple ((6, 26), 'U') only you can tell if that's a legitimate result, or an unexpected one. if it's *expected* that there will be some mismatches, you can do this: try: values = np.array([Q[state,a] for a in actions]) except KeyError: # take appropriate action for missing key If it's unexpected, then you have some recoding to do. From savageapple850 at gmail.com Fri Jun 26 11:00:58 2020 From: savageapple850 at gmail.com (Cravan) Date: Fri, 26 Jun 2020 23:00:58 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> <634f3789-fc67-f824-83c5-1282e61079ab@wichmann.us> Message-ID: <9686CFFE-0C15-4EDE-859A-A4C12DB82465@gmail.com> Hi Mats, Sorry for the late reply. Thanks for your suggestion, I realised that Q was merely giving only some values due to my class settings. However, I have no idea how to set all the coordinates as my state Space. Assuming WIDTH and HEIGHT are the width and height of my env respectively, how should I define my state space within the class itself? Something like this (although this is wrong) : self.stateSpace = [(i for i in range(int(WIDTH)), q for q in range(int(HEIGHT)))] Essentially my logic is for each number in range(Width), pair it to a number in range(HEIGHT). How should I rectify the code above so as to fit my logic while also conforming to "Pythonic" laws? Cravan ?On 26/6/20, 10:43 PM, "Tutor on behalf of Mats Wichmann" wrote: On 6/26/20 8:25 AM, Cravan wrote: > Sadly, an error pops up when I change the code. > Here's my edited code for the class file: > However, this error pops up: > ####### > Traceback (most recent call last): > File "maze.py", line 181, in > g.run() > File "maze.py", line 53, in run > self.update() > File "maze.py", line 109, in update > action_ = maxAction(Q, observationnew, possible_actions) > File "maze.py", line 177, in maxAction > values = np.array([Q[state,a] for a in actions]) > File "maze.py", line 177, in > values = np.array([Q[state,a] for a in actions]) > KeyError: ((6, 26), 'U') > ###### > > Apologies for the (late) and long email here, would appreciate if someone could offer some help. Well, again the error tells you what is happening: KeyError means you tried to look up a key in a dictionary that is actually not present in the dictionary. So Q does not contain the tuple ((6, 26), 'U') only you can tell if that's a legitimate result, or an unexpected one. if it's *expected* that there will be some mismatches, you can do this: try: values = np.array([Q[state,a] for a in actions]) except KeyError: # take appropriate action for missing key If it's unexpected, then you have some recoding to do. _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From PyTutor at danceswithmice.info Fri Jun 26 20:12:54 2020 From: PyTutor at danceswithmice.info (dn) Date: Sat, 27 Jun 2020 12:12:54 +1200 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> Message-ID: On 27/06/20 2:25 AM, Cravan wrote: > Sadly, an error pops up when I change the code. > Here's my edited code for the class file: > ```` > class Zomb(pg.sprite.Sprite): > def __init__(self, game, x, y): > self.groups = game.all_sprites, game.zombs > pg.sprite.Sprite.__init__(self, self.groups) > self.game = game > self.image = game.zomb_img > self.rect = self.image.get_rect() > #image = image provided in game > self.x = x > self.y = y > self.pos = (x, y) > #this is each state > #possible states > for a in range(int(GRIDWIDTH)): > for b in range(int(GRIDHEIGHT)): > self.stateSpace = [(a,b)] > self.actionSpace = {'U': - 1, 'D': 1, > 'L': - 1, 'R': 1} > #corresponding adjustments > self.possibleActions = ['U', 'D', 'L', 'R'] > #list of possible actions > self.vel = 0 > self.acc = 0 > self.rect.center = vec(self.x, self.y) > self.rotate = 0 > > def setState(self, state): > self.pos = state > > def TerminalState(self, state): > if self.game.health == 0: > return True > else: > return False > > def step(self, action): > x, y = self.x, self.y > if self.actionSpace[action] == 'U': > self.y = self.y + 1 > elif self.actionSpace[action] == 'D': > self.y = self.y - 1 > elif self.actionSpace[action] == 'R': > self.x = self.x + 1 > elif self.actionSpace[action] == 'L': > self.x = self.x - 1 > resultingState = (self.x, self.y) > self.game.reward = -1 if not self.TerminalState(resultingState) else 0 > self.setState(resultingState) > > > return resultingState, self.game.reward,\ > self.TerminalState(resultingState), None > > def actionSpaceSample(self): > return np.random.choice(self.possibleActions) > > def update(self): > self.rotate = (self.game.player.pos - self.rect.center).angle_to(vec(1, 0)) > self.image = self.game.zomb_img > self.rect = self.image.get_rect() > self.acc = vec(ZOMB_SPEED, 0).rotate(-self.rotate) > ```` > And here's my edited main implementation now in the update() function: > ``` > ALPHA = 0.1 > GAMMA = 1.0 > EPS = 1.0 > Q = {} > > for zomb in self.zombs: > print(zomb.stateSpace) > for state in zomb.stateSpace: > for action in zomb.possibleActions: > Q[state, action] = 0 > numGames = 10 > totalRewards = np.zeros(numGames) > for i in range(numGames): > > print('starting game ', i + 1) > epRewards = 0 > > rand = np.random.random() > for zomb in self.zombs: > observation = zomb.pos > #state > action = maxAction(Q, observation, zomb.possibleActions) if rand < (1-EPS) \ > else zomb.actionSpaceSample() > #choosing the best action possible > > observationnew, reward, done, info = zomb.step(action) > epRewards += reward > > for zomb in self.zombs: > possible_actions = zomb.possibleActions > action_ = maxAction(Q, observationnew, possible_actions) > > Q[observation,action] = Q[observation,action] + ALPHA*(reward + \ > GAMMA*Q[observationnew,action_] - Q[observation,action]) > observation = observationnew > if EPS - 2 / numGames > 0: > EPS -= 2 / numGames > else: > EPS = 0 > totalRewards[i] = epRewards > ``` > However, this error pops up: > ####### > Traceback (most recent call last): > File "maze.py", line 181, in > g.run() > File "maze.py", line 53, in run > self.update() > File "maze.py", line 109, in update > action_ = maxAction(Q, observationnew, possible_actions) > File "maze.py", line 177, in maxAction > values = np.array([Q[state,a] for a in actions]) > File "maze.py", line 177, in > values = np.array([Q[state,a] for a in actions]) > KeyError: ((6, 26), 'U') > ###### It may be worth taking a step-back - both in terms of the design you are implementing and the questions you are asking of us:- Have looked and looked, and then used 'find', but failed to find the code-line at-error. Why? [help us to help you!] Aside from learning Python's idioms, are you using a competent IDE? Could you then use full-names instead of abbreviations, without adding major effort? I think we could guess what a "zomb" is, but would it be better (and kinder) to remove all doubt? Have comments and "docstrings" (a pythonic idiom) been used to describe what the code/each function is supposed to do, and why? If the game's environment is described as a "grid", why is its width and height described using anything other than int[eger]s? What is the purpose of "state"? Is there a difference between "state" and "position" (or next-/previous-position)? Have you understood the (animation) concept of collision? (assuming that is part of the intent here) Have you noted various algorithms and approximations which are commonly-used? -- Regards =dn From bouncingcats at gmail.com Fri Jun 26 21:35:57 2020 From: bouncingcats at gmail.com (David) Date: Sat, 27 Jun 2020 11:35:57 +1000 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> Message-ID: On Sat, 27 Jun 2020 at 00:32, John Weller wrote: I have a Python program which will be running 24/7 (I hope ?). It is > generating data in a file which I want to clean up overnight. The way I am > looking at doing it is to run a separate program as a Cron job at midnight > ? will that work? The alternative is to add it to the loop and check for > the time. > Hi, can you more fully describe the complete situation? I just have a hunch that you haven't given enough information to generate very helpful replies. How much data is involved? How quickly does it accumulate? Why do you want to clean it "overnight", does it go to sleep? What is the hardware and OS platform? Also, can you explain why you believe that whatever "cleaning" you need must be done by a separate program? Because that is a rather important design decision with many consequences. I guess you have your reasons, but you haven't shared them or the big picture with us. Without that information, this reads like a classic "XY" question: https://en.wikipedia.org/wiki/XY_problem The problem with that kind of question is that it restricts the ability of people to assist you. I suggest that if you give the bigger picture then that will increase the scope for people here to offer educational and useful replies, the reason why the *tutor* list exists. > I have tried researching this but only got even more confused. People here are pretty good at offering great guidance, if you describe the problem fully. Try not to narrow the solution space because of your own confusion. I write this advice from the perspective of someone who mostly reads this list to learn. In this case I don't expect to have any answers, but I hope that if you describe what you are doing more completely, then that will create an opportunity for others to share their expertise in Python or data acquisition or concurrent processing or whatever else with all of us. From savageapple850 at gmail.com Fri Jun 26 21:44:26 2020 From: savageapple850 at gmail.com (Cravan) Date: Sat, 27 Jun 2020 09:44:26 +0800 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> Message-ID: <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com> ?> On 27/6/20, 8:13 AM, "Tutor on behalf of dn via Tutor" wrote: > It may be worth taking a step-back - both in terms of the design you are implementing and the questions you are asking of us:- Sure! I apologise for any inconvenience caused, and really appreciate your efforts to help me > Have looked and looked, and then used 'find', but failed to find the code-line at-error. Why? [help us to help you!] Essentially right now my dictionary is only churning out values of a current index when printing it out, so e.g. {((1023, 767), 'U'): 0, ((1023, 767), 'D'): 0, ((1023, 767), 'L'): 0, ((1023, 767), 'R'): 0} when it's supposed to be inclusive of all the coords. in the game (and the possible actions). I can't seem to rectify it(I don't know how). > Aside from learning Python's idioms, are you using a competent IDE? Could you then use full-names instead of abbreviations, without adding major effort? I think we could guess what a "zomb" is, but would it be better (and kinder) to remove all doubt? I'm using Atom to do it. An enemy in this case would be a zombie.(zomb) who is seeking to kill the player. The player has a health bar which decreases when the zombie touches it, and my game is a maze game. The zombies can pass through walls to give them an advantage over the player (making it more difficult) > Have comments and "docstrings" (a pythonic idiom) been used to describe what the code/each function is supposed to do, and why? Well, some (haha). > If the game's environment is described as a "grid", why is its width and height described using anything other than int[eger]s? Width and Height are the actual width and height. Essentially gridwidth and gridheight are the width and height (in tilesize units) e.g. 3 tiles x 4 tiles for example > What is the purpose of "state"? Is there a difference between "state" and "position" (or next-/previous-position)? A state is essentially the current state of the system (i.e. I can set the state as the product of my coordinates, for example but now I'm using it as the coords. for convenience), within a set of states (product of the maximum y-coord and the max. x-coord but it also can be all the coords in my environment(which I am using)) > Have you understood the (animation) concept of collision? (assuming that is part of the intent here) Have you noted various algorithms and approximations which are commonly-used? Yes, the collision part is fine since I was able to get it to work before the implementation of machine learning -- Regards =dn _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From jf_byrnes at comcast.net Sat Jun 27 12:44:09 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 11:44:09 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite Message-ID: I am writing a script that will delete unwanted cookies from the Firefox cookies.sqlite file based on a white list. I found that I could not connect to the file in my profile directory when Firefox is active. If I copy cookies.sqlite to a temporary location the script will connect to the db and delete unwanted cookies. The problem is when I copy the file back to my profile directory and use preferences to check for cookies, the deleted cookies have reappeared. This seems to be the result of a file called cookies.sqlite-wal in the same directory. More info on sqlite-wal here: https://sqlite.org/wal.html Based on what I read in the above link and some googling it looked like the cookies.sqlite-wal file had not yet updated the cookies.sqlite file. So I copied the cookies.sqlite file and looked at it with a db viewer and the cookies I wanted to delete were not there. So I copied the cookies.sqlite-wal file to the same location and then ran this portion of the script and the cookies appeared in the db. def sqlite3Connect(): ''' Connect to cookies database ''' conn = sqlite3.connect(WORK_AREA + "cookies.sqlite") conn.execute('PRAGMA wal_checkpoint(TRUNCATE)') return conn Checking the db the cookies I wanted to delete were now in the db. I then ran the part of the script that deleted the cookies. After running the db viewer I could see the cookies had been deleted. However when I deleted the cookies.sqlite and cookes.sqlite-wal files from my firefox profile and copied my updated cookies.sqlite file to my profile, checking with firefox still showed the cookies I tried to delete. At this point I am out of ideas and wondering if anyone knows how to successfully manipulate this file? Thanks, Jim From alan.gauld at yahoo.co.uk Sat Jun 27 13:03:16 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 27 Jun 2020 18:03:16 +0100 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On 27/06/2020 17:44, Jim wrote: > The problem is when I copy the file back to my profile directory and use > preferences to check for cookies, the deleted cookies have reappeared. > This seems to be the result of a file called cookies.sqlite-wal in the > same directory. I assume you are closing all instances of Firefox down before copying the new file into place? Otherwise Firefox is probably overwriting it from a cache in memory or somesuch. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jf_byrnes at comcast.net Sat Jun 27 14:02:45 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 13:02:45 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote: > On 27/06/2020 17:44, Jim wrote: > >> The problem is when I copy the file back to my profile directory and use >> preferences to check for cookies, the deleted cookies have reappeared. >> This seems to be the result of a file called cookies.sqlite-wal in the >> same directory. > > I assume you are closing all instances of Firefox down before copying > the new file into place? Otherwise Firefox is probably overwriting it > from a cache in memory or somesuch. > No I am trying to do it without shutting down Firefox. I normally have 3 instances of Firefox open. 2 private and 1 normal. It's the normal one I am working on. At the end of the day I manually remove cookies I don't want so I am trying to automate the process. If I had to manually shut down all instances Firefox it would defeat the purpose of automation. If I can't find another solution I may try to just programmatically shut down the normal one, the private ones normally have multiple tabs open and I don't want to close them. Years ago I had a problem with Firefox crashing when trying to reopen tabs and since then I have always turned that setting off. Regards, Jim From robertvstepp at gmail.com Sat Jun 27 14:10:57 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 27 Jun 2020 13:10:57 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On Sat, Jun 27, 2020 at 1:02 PM Jim wrote: > ... Years ago I had a problem with Firefox > crashing when trying to reopen tabs and since then I have always turned > that setting off. Perhaps this has been improved in current versions of Firefox? I have yet to experience this issue since I have switched to Firefox about two or three years ago. My tabs have always been seamlessly restored for multiple instances of Firefox windows open. -- boB From Richard at Damon-Family.org Sat Jun 27 14:16:54 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Sat, 27 Jun 2020 14:16:54 -0400 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> On 6/27/20 2:02 PM, Jim wrote: > On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote: >> On 27/06/2020 17:44, Jim wrote: >> >>> The problem is when I copy the file back to my profile directory and >>> use >>> preferences to check for cookies, the deleted cookies have reappeared. >>> This seems to be the result of a file called cookies.sqlite-wal in the >>> same directory. >> >> I assume you are closing all instances of Firefox down before copying >> the new file into place? Otherwise Firefox is probably overwriting it >> from a cache in memory or somesuch. >> > > No I am trying to do it without shutting down Firefox. I normally have > 3 instances of Firefox open. 2 private and 1 normal. It's the normal > one I am working on. At the end of the day I manually remove cookies I > don't want so I am trying to automate the process. If I had to > manually shut down all instances Firefox it would defeat the purpose > of automation. If I can't find another solution I may try to just > programmatically shut down the normal one, the private ones normally > have multiple tabs open and I don't want to close them. Years ago I > had a problem with Firefox crashing when trying to reopen tabs and > since then I have always turned that setting off. > > Regards,? Jim Just because a program uses a sqlite database, doesn't mean that it intends for you to be able to interact with it by changing that database. You are probably locked out of directly operating on it by the program having a write lock on the database, thus blocking you from updating it. Deleting the file and replacing with the database open is one of the items on the list of how to corrupt your database. Likely the pages with the cookies are in program cache memory, and spooled out at some point when updated. I would look at writing a Firefox extension to do the cookie cleanup (if there isn't one already that does a close enough job) rather than something outside of Firefox. -- Richard Damon From jf_byrnes at comcast.net Sat Jun 27 14:23:05 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 13:23:05 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On 6/27/20 1:10 PM, boB Stepp wrote: > On Sat, Jun 27, 2020 at 1:02 PM Jim wrote: >> ... Years ago I had a problem with Firefox >> crashing when trying to reopen tabs and since then I have always turned >> that setting off. > > Perhaps this has been improved in current versions of Firefox? I have > yet to experience this issue since I have switched to Firefox about > two or three years ago. My tabs have always been seamlessly restored > for multiple instances of Firefox windows open. > > That's probably true but I guess old habits die hard. Regards, Jim From jf_byrnes at comcast.net Sat Jun 27 14:31:30 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 13:31:30 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> Message-ID: On 6/27/20 1:16 PM, Richard Damon wrote: > On 6/27/20 2:02 PM, Jim wrote: >> On 6/27/20 12:03 PM, Alan Gauld via Tutor wrote: >>> On 27/06/2020 17:44, Jim wrote: >>> >>>> The problem is when I copy the file back to my profile directory and >>>> use >>>> preferences to check for cookies, the deleted cookies have reappeared. >>>> This seems to be the result of a file called cookies.sqlite-wal in the >>>> same directory. >>> >>> I assume you are closing all instances of Firefox down before copying >>> the new file into place? Otherwise Firefox is probably overwriting it >>> from a cache in memory or somesuch. >>> >> >> No I am trying to do it without shutting down Firefox. I normally have >> 3 instances of Firefox open. 2 private and 1 normal. It's the normal >> one I am working on. At the end of the day I manually remove cookies I >> don't want so I am trying to automate the process. If I had to >> manually shut down all instances Firefox it would defeat the purpose >> of automation. If I can't find another solution I may try to just >> programmatically shut down the normal one, the private ones normally >> have multiple tabs open and I don't want to close them. Years ago I >> had a problem with Firefox crashing when trying to reopen tabs and >> since then I have always turned that setting off. >> >> Regards,? Jim > > Just because a program uses a sqlite database, doesn't mean that it > intends for you to be able to interact with it by changing that > database. You are probably locked out of directly operating on it by the > program having a write lock on the database, thus blocking you from > updating it. I'm sure that is the case and is why I tried moving it. > Deleting the file and replacing with the database open is one of the > items on the list of how to corrupt your database. Likely the pages with > the cookies are in program cache memory, and spooled out at some point > when updated. I didn't mention it but I do have a copy of both files right after I manually cleaned them from inside Firefox. > I would look at writing a Firefox extension to do the cookie cleanup (if > there isn't one already that does a close enough job) rather than > something outside of Firefox. I know I don't have the expertise to do that. Having to manually delete some cookies is not a big deal, I just enjoy programing with Python so I look for things I can automate. Regards, Jim > From mats at wichmann.us Sat Jun 27 14:33:12 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 27 Jun 2020 12:33:12 -0600 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On 6/27/20 12:23 PM, Jim wrote: > On 6/27/20 1:10 PM, boB Stepp wrote: >> On Sat, Jun 27, 2020 at 1:02 PM Jim wrote: >>> ... Years ago I had a problem with Firefox >>> crashing when trying to reopen tabs and since then I have always turned >>> that setting off. >> >> Perhaps this has been improved in current versions of Firefox?? I have >> yet to experience this issue since I have switched to Firefox about >> two or three years ago.? My tabs have always been seamlessly restored >> for multiple instances of Firefox windows open. >> >> > > That's probably true but I guess old habits die hard. > > Regards,? Jim Firefox still forgets its brain sometimes. I use an extension Tab Session Manager which seems to solve that problem. The issue with that problem being solved is I accumulate too many tabs... 500-600 open on my main Linux box is not at all uncommon. Tab Session Manager writes out a json file with the tabs periodically, plus on events (like browser close), and I've found it very reliable. From mats at wichmann.us Sat Jun 27 14:35:45 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 27 Jun 2020 12:35:45 -0600 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> Message-ID: <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> On 6/27/20 12:31 PM, Jim wrote: >> I would look at writing a Firefox extension to do the cookie cleanup (if >> there isn't one already that does a close enough job) rather than >> something outside of Firefox. > > I know I don't have the expertise to do that. Having to manually delete > some cookies is not a big deal, I just enjoy programing with Python so I > look for things I can automate. There's something called SpeedyFox - it's not a plugin - which knows how to clean up/compact sqlite databases for many browsers (and Thunderbird), but I'm not aware that it operates on the cookie database. And it does ask that you shut down the browser before cleaning... From jf_byrnes at comcast.net Sat Jun 27 14:46:51 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 13:46:51 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: Message-ID: On 6/27/20 1:33 PM, Mats Wichmann wrote: > On 6/27/20 12:23 PM, Jim wrote: >> On 6/27/20 1:10 PM, boB Stepp wrote: >>> On Sat, Jun 27, 2020 at 1:02 PM Jim wrote: >>>> ... Years ago I had a problem with Firefox >>>> crashing when trying to reopen tabs and since then I have always turned >>>> that setting off. >>> >>> Perhaps this has been improved in current versions of Firefox?? I have >>> yet to experience this issue since I have switched to Firefox about >>> two or three years ago.? My tabs have always been seamlessly restored >>> for multiple instances of Firefox windows open. >>> >>> >> >> That's probably true but I guess old habits die hard. >> >> Regards,? Jim > > Firefox still forgets its brain sometimes. > > I use an extension Tab Session Manager which seems to solve that > problem. The issue with that problem being solved is I accumulate too > many tabs... 500-600 open on my main Linux box is not at all uncommon. > Tab Session Manager writes out a json file with the tabs periodically, > plus on events (like browser close), and I've found it very reliable. > Wow, I can't imagine having that many open, I don't even have that many bookmarks. At most I have 8 or 10 open and that's when I am researching something. When I am done I close them. I guess I need to ask, why do you have that many open and how do you even know what is open? Regards, Jim From jf_byrnes at comcast.net Sat Jun 27 15:02:37 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 14:02:37 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> Message-ID: On 6/27/20 1:35 PM, Mats Wichmann wrote: > On 6/27/20 12:31 PM, Jim wrote: > >>> I would look at writing a Firefox extension to do the cookie cleanup (if >>> there isn't one already that does a close enough job) rather than >>> something outside of Firefox. >> >> I know I don't have the expertise to do that. Having to manually delete >> some cookies is not a big deal, I just enjoy programing with Python so I >> look for things I can automate. > > There's something called SpeedyFox - it's not a plugin - which knows how > to clean up/compact sqlite databases for many browsers (and > Thunderbird), but I'm not aware that it operates on the cookie database. > And it does ask that you shut down the browser before cleaning... > When I get a chance I'll try shutting down just the normal one and see if that helps. Regards, Jim From alan.gauld at yahoo.co.uk Sat Jun 27 18:41:48 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 27 Jun 2020 23:41:48 +0100 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> Message-ID: On 27/06/2020 20:02, Jim wrote: > When I get a chance I'll try shutting down just the normal one and see > if that helps. I'll be surprised. All instances of firefox will use the same cookie database. If it gets deleted they will just regenerate it using the in-memory cache. They are using sqlite as a persistence mechanism not a database. Its table structures are used just as a useful data format and to provide basic multi-session access/locking control. But so long as there is a single instance running you probably can't even guarantee that changes made by the other instances (let alone any external program) will stick. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sat Jun 27 19:05:39 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 28 Jun 2020 09:05:39 +1000 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> Message-ID: <20200627230539.GA56218@cskk.homeip.net> On 26Jun2020 11:21, John Weller wrote: >I have a Python program which will be running 24/7 (I hope ?). It is >generating data in a file which I want to clean up overnight. The way >I am looking at doing it is to run a separate program as a Cron job at >midnight ? will that work? The alternative is to add it to the loop >and check for the time. I have tried researching this but only got even >more confused. Running a separate program is perfectly reasonable. And crontab is a perfect place for a regular task like this. The primary issue usually is that you do not want both programms to be using the file at the same time. Supposing the file were, say, a CSV file to which your long running programme (A) appended data. ANd that the clean up program (B) reads the CSV file, tidies some stuff, and rewrites the CSV file. You can imagine this sequence: - programme B opens the file and reads the data - programme B thinks about the data to clean it - programme A appends more data to the file - programme B rewrites the clean data into the file, _overwriting_ the new data programme A just appended The usual process with a shared external file is to use a lock facility. These come in a few forms, and it is essential that both programme A and programme B use the same locking system. One of the easiest and most portable is to make a lock file while you work with the file. If your data file is called "foo" you might use a lock fie called "foo.lock". On a UNIX type system (includes Linux) you can atomicly make such a file like this: import os ....... lockpath = datafilepath + '.lock' lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0) That is a special mode of the OS "open" call (_not_ Python's default "open" builtin) whose parameters have the following meanings: - os.O_CREAT: create the file if missing - os.O_EXCL: ensure that the file is created - if it already exists this raises an exception - os.O_RDWR: open the file for read and write - 0: the initial permissions, ensuring that the file is _not_ readable or writable See "man 2 open" on a UNIX system for the spec. The combination of O_RDWR and 0 permissions means that if the file already exists (made by the "other" programme) then it won't have any permissions, which means we won't get read or write access and the open will fail. The nice thing about this is that the initial permissions are _immediate_ when the file is created by the OS - there's no tiny window where the file has read/write perms which then get removed - the OS ensures it. This is nice on networked file shares (if they are reliable). Anyway, the upshort of the os.open() call above is that if the lockfile already exists, the open will fail, and otherwise it will succeed, preventing antoehr programme doing the same thing. When finished, close the lockfd and remove the lock file: os.close(lockfd) os.remove(lockpath) No, because the whole scenario is that occasionally both programms want the file at the same time, the os.open _will_ fail in that case. SO the idea is that you repeat it until it succeeds, then do your work: while True: try: lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0) except OSError as e: print("lock not obtained, sleeping") time.sleep(1) else: break .... work with the data file ... os.close(lockfd) os.remove(lockpath) Put that logic in both programmes and you should be ok. You can see a more elaborate version of this logic in my "makelockfile" function here: https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/fileutils.py#lines-527 (Atlassian are going to nuke that repo soon, alas, because they find mercurial too hard. But until then the link should be good.) Cheers, Cameron Simpson From PyTutor at DancesWithMice.info Sat Jun 27 19:26:02 2020 From: PyTutor at DancesWithMice.info (dn) Date: Sun, 28 Jun 2020 11:26:02 +1200 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> Message-ID: <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info> On 28/06/20 10:41 AM, Alan Gauld via Tutor wrote: > On 27/06/2020 20:02, Jim wrote: >> When I get a chance I'll try shutting down just the normal one and see >> if that helps. > > I'll be surprised. All instances of firefox will use the same > cookie database. If it gets deleted they will just regenerate > it using the in-memory cache. They are using sqlite as a > persistence mechanism not a database. Its table structures > are used just as a useful data format and to provide basic > multi-session access/locking control. > > But so long as there is a single instance running you probably > can't even guarantee that changes made by the other instances > (let alone any external program) will stick. +1 "Persistence", except that there is a periodic (by config-setting) update/backup. Exactly! The live system is not continually/regularly re-reading the 'database' because it already (thinks it) 'knows' what's going-on. The problem is ultimately one of 'ownership'. If it is 'my' data, I will decide the who/what/why of access, etc! FF does *not* expect (or want?) to share these records with anyone or anything else. Accordingly, they have not been designed for multi-access (per a regular RDBMS). Yes, if the relevant FF instance (see below) has been closed-down, and the files are altered, this idea may succeed, but once-again, that would be doing something most likely to be outside of any FF design considerations - here be dragons! (further to previous-post, above) There *may* be different 'databases' - because FF works from a "profile" and can be made to configure itself from multiple profiles on the single machine/OpSys - thus in the days when PCs were often shared, different students could use the same machine but keep their data separate, 'his' and 'hers' at home, and so-on. Largely unused by most, but still available/possible. Finally, (yes, am showing-off here) the Firefox [Web] Developer Edition (and quite possibly other 'special versions' of FF) install separately and outside the usual system-wide context - (stated to be) primarily to maintain separate settings, profiles, etc. So, the multiple versions of Firefox not only have separate profiles but also keep them in a different (default) location. (Firefox can be instructed where to keep its profiles, should one not wish to accept their default/recommendation) Back to the OP: I salute your brave efforts, and your intent to use Python. However, the issues are more to do with FF than Python. Thus, you may find more help and advice from MDN (the Mozilla Developers' Network). There is an Add-on/Extension called Cookie-Editor which will list the cookies relevant to the active tab/web-page, and gives one the opportunity to delete them (and more). This is considerably more accessible (and flexible - and revealing!) than using the Preferences | Privacy and Security facility! I use it for controlling and debugging the cookie side of web-dev 'all the time'... At the sledge-hammer end of the tool-rack, it is possible to set Firefox to wipe all cookies at the end of each session. This will definitely counter any sneaky marketing efforts and 'tracking', but may also have the effect of undoing the 'remember me' type of facility on sites where you may wish to maintain a 'membership'... -- Regards =dn From mats at wichmann.us Sat Jun 27 21:27:43 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 27 Jun 2020 19:27:43 -0600 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> Message-ID: On June 26, 2020 4:21:02 AM MDT, John Weller wrote: >I have a Python program which will be running 24/7 (I hope ?). It is >generating data in a file which I want to clean up overnight. The way >I am looking at doing it is to run a separate program as a Cron job at >midnight ? will that work? The alternative is to add it to the loop >and check for the time. I have tried researching this but only got even >more confused. > > > >Thanks > > > >John > > > >John Weller > >01380 723235 > >07976 393631 > > > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor a common technique is a "log rotate" one... I see it's got a wikipedia page, take a look for some ideas. -- Sent from a mobile device with K-9 Mail. Please excuse my brevity. From jf_byrnes at comcast.net Sat Jun 27 22:18:19 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 21:18:19 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> Message-ID: On 6/27/20 5:41 PM, Alan Gauld via Tutor wrote: > On 27/06/2020 20:02, Jim wrote: > >> When I get a chance I'll try shutting down just the normal one and see >> if that helps. > > I'll be surprised. All instances of firefox will use the same > cookie database. If it gets deleted they will just regenerate > it using the in-memory cache. They are using sqlite as a > persistence mechanism not a database. Its table structures > are used just as a useful data format and to provide basic > multi-session access/locking control. > > But so long as there is a single instance running you probably > can't even guarantee that changes made by the other instances > (let alone any external program) will stick. > You're probably right. Just thinking, with no real basis to do so, that private mode does not retain cookies so maybe there is no reason for it to use cookies.sqlite-wal. Anyway I've come this far, the script is written and works until Firefox does it's thing, so I might as well try one last time. Thanks, Jim From jf_byrnes at comcast.net Sat Jun 27 22:30:04 2020 From: jf_byrnes at comcast.net (Jim) Date: Sat, 27 Jun 2020 21:30:04 -0500 Subject: [Tutor] Advice on working with Firefox's cookies.sqlite In-Reply-To: <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info> References: <7062cb97-76a8-c4ec-97af-90fe25956d42@Damon-Family.org> <52a32798-4c29-9d38-1af9-058e587c9022@wichmann.us> <36f01a1e-b5d8-a6a8-c0df-0a7cf11e14ff@DancesWithMice.info> Message-ID: On 6/27/20 6:26 PM, dn via Tutor wrote: > On 28/06/20 10:41 AM, Alan Gauld via Tutor wrote: >> On 27/06/2020 20:02, Jim wrote: >>> When I get a chance I'll try shutting down just the normal one and see >>> if that helps. >> >> I'll be surprised. All instances of firefox will use the same >> cookie database. If it gets deleted they will just regenerate >> it using the in-memory cache. They are using sqlite as a >> persistence mechanism not a database. Its table structures >> are used just as a useful data format and to provide basic >> multi-session access/locking control. >> >> But so long as there is a single instance running you probably >> can't even guarantee that changes made by the other instances >> (let alone any external program) will stick. > > > +1 "Persistence", except that there is a periodic (by config-setting) > update/backup. > > Exactly! The live system is not continually/regularly re-reading the > 'database' because it already (thinks it) 'knows' what's going-on. > > The problem is ultimately one of 'ownership'. If it is 'my' data, I will > decide the who/what/why of access, etc! > > FF does *not* expect (or want?) to share these records with anyone or > anything else. Accordingly, they have not been designed for multi-access > (per a regular RDBMS). Yes, if the relevant FF instance (see below) has > been closed-down, and the files are altered, this idea may succeed, but > once-again, that would be doing something most likely to be outside of > any FF design considerations - here be dragons! > > > (further to previous-post, above) > There *may* be different 'databases' - because FF works from a "profile" > and can be made to configure itself from multiple profiles on the single > machine/OpSys - thus in the days when PCs were often shared, different > students could use the same machine but keep their data separate, 'his' > and 'hers' at home, and so-on. Largely unused by most, but still > available/possible. > > Finally, (yes, am showing-off here) the Firefox [Web] Developer Edition > (and quite possibly other 'special versions' of FF) install separately > and outside the usual system-wide context - (stated to be) primarily to > maintain separate settings, profiles, etc. So, the multiple versions of > Firefox not only have separate profiles but also keep them in a > different (default) location. > (Firefox can be instructed where to keep its profiles, should one not > wish to accept their default/recommendation) > > > Back to the OP: > I salute your brave efforts, and your intent to use Python. However, the > issues are more to do with FF than Python. Thus, you may find more help > and advice from MDN (the Mozilla Developers' Network). That's thought, thanks. > There is an Add-on/Extension called Cookie-Editor which will list the > cookies relevant to the active tab/web-page, and gives one the > opportunity to delete them (and more). This is considerably more > accessible (and flexible - and revealing!) than using the Preferences | > Privacy and Security facility! I use it for controlling and debugging > the cookie side of web-dev 'all the time'... > > At the sledge-hammer end of the tool-rack, it is possible to set Firefox > to wipe all cookies at the end of each session. This will definitely > counter any sneaky marketing efforts and 'tracking', but may also have > the effect of undoing the 'remember me' type of facility on sites where > you may wish to maintain a 'membership'... I won't pick up the sledge-hammer. My aim is to keep the cookies that benefit me and get rid of the ones that don't. Its not that time consuming to manually delete the unwanted cookies at the end of the day. I just thought it would be an interesting python project. Regards, Jim From PyTutor at DancesWithMice.info Sun Jun 28 02:21:08 2020 From: PyTutor at DancesWithMice.info (dn) Date: Sun, 28 Jun 2020 18:21:08 +1200 Subject: [Tutor] TypeError: unhashable type: 'pygame.math.Vector2' In-Reply-To: <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com> References: <9a017e45-1b5d-283e-599a-ce2b89ff6b8c@wichmann.us> <8CB3E487-0589-4A6C-AEA4-3E047ADABEE8@gmail.com> <0939A782-B418-4F8A-8B2F-8FDD759D0A58@gmail.com> Message-ID: On 27/06/20 1:44 PM, Cravan wrote: > ?> On 27/6/20, 8:13 AM, "Tutor on behalf of dn via Tutor" wrote: > > > > It may be worth taking a step-back - both in terms of the design you are > implementing and the questions you are asking of us:- > Sure! I apologise for any inconvenience caused, and really appreciate your efforts to help me It's not inconvenience, per-se, more a thought that sometimes 'the problem' may not be a 'programming error', but instead be a short-coming in design... (I don't know! However, you will see more of that level of question, below) > > Have looked and looked, and then used 'find', but failed to find the > code-line at-error. Why? [help us to help you!] > Essentially right now my dictionary is only churning out values of a current index when printing it out, so e.g. > {((1023, 767), 'U'): 0, ((1023, 767), 'D'): 0, ((1023, 767), 'L'): 0, ((1023, 767), 'R'): 0} when it's supposed to be inclusive of all the coords. in the game (and the possible actions). I can't seem to rectify it(I don't know how). So, you didn't include this information!? The more generous you can be with us, the more readily folk will dive-in to help you. You will see (below) that one problem may be purely Python, thus even those who do not use Pygame could have been helping, given the info... Please see previous msg - covering the generation of different views of the same data/data-components. Why look at all possible coordinates, cf only those occupied by players, zombies, and obstructions? (see later) Regardless, to be able to see what's (not) happening, insert a debug-print after self.stateSpace = [(a,b)] (and the nested for-loops), run, and observe... What is the content of self.stateSpace, its type(), and its len()? If that is not sufficient to provoke an 'ahah!', then put another debug-print 'inside' the loops... My guess is that you have confused the syntax for a list comprehension with that appropriate to explicit, nested, for-loops. To add elements to the end of a list, use list.append( value ) - see Python Docs for more info. Another [design] question, if I may: might it be better to use a dict[ionary] so that (later) you could have either "serial" or "direct-access" to 'squares' (coordinates) in the game's grid? > > Aside from learning Python's idioms, are you using a competent IDE? > Could you then use full-names instead of abbreviations, without adding > major effort? I think we could guess what a "zomb" is, but would it be > better (and kinder) to remove all doubt? > I'm using Atom to do it. IIRC once a variable-name has been entered, next time the entry being typed appears to be similar, Atom will offer to 'fill' for you - saving typing *and* improving readability... An enemy in this case would be a zombie.(zomb) who is seeking to kill the player. The player has a health bar which decreases when the zombie touches it, and my game is a maze game. The zombies can pass through walls to give them an advantage over the player (making it more difficult) So, (one) "collision" is defined as a zombie either landing on the same 'square' as the player, or on a neighboring square. Which, and (expressed in English) how do you see this as a calculation (and data-structure)? > > Have comments and "docstrings" (a pythonic idiom) been used to describe > what the code/each function is supposed to do, and why? > Well, some (haha). Recognising that there is a difference between someone working by-and-for himself, and someone who is part of a team; by involving us have you effectively moved from one to the other? ie would improving this situation help us to understand your thinking and thus move more rapidly towards an 'answer'? > > If the game's environment is described as a "grid", why is its width and > height described using anything other than int[eger]s? > Width and Height are the actual width and height. Essentially gridwidth and gridheight are the width and height (in tilesize units) e.g. 3 tiles x 4 tiles for example Which strike me as integers! (yet the code calls int() to convert them, but from what?) Also, how many times does the code perform these conversions, cf the number of times that it is strictly-necessary? > > What is the purpose of "state"? Is there a difference between "state" > and "position" (or next-/previous-position)? > A state is essentially the current state of the system (i.e. I can set the state as the product of my coordinates, for example but now I'm using it as the coords. for convenience), within a set of states (product of the maximum y-coord and the max. x-coord but it also can be all the coords in my environment(which I am using)) With apologies, but I failed to understand. Is "state" related to whether the game is 'on' or over? Is it the ability of the player (or each zombie) to move into a neighboring square/tile? Something else? How would you express its purpose and functions, in English? The "all the coords" part is (hopefully) addressed with the debug-print investigation proposed, above. > > Have you understood the (animation) concept of collision? (assuming that > is part of the intent here) Have you noted various algorithms and > approximations which are commonly-used? > Yes, the collision part is fine since I was able to get it to work before the implementation of machine learning -- Regards =dn From john at johnweller.co.uk Sun Jun 28 05:59:16 2020 From: john at johnweller.co.uk (John Weller) Date: Sun, 28 Jun 2020 10:59:16 +0100 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <20200627230539.GA56218@cskk.homeip.net> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> <20200627230539.GA56218@cskk.homeip.net> Message-ID: <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk> Thank you to all who responded. I was conscious of the file locking issue and had a strategy in mind to cope. My concern was if Python could manage. I am an experienced programmer new to Python and had visions of the early interpreted languages I used such as those on the BBC Micro and early PCs ? Thanks again John John Weller 01380 723235 07976 393631 -----Original Message----- From: Cameron Simpson Sent: 28 June 2020 00:06 To: John Weller Cc: 'Python Tutor' Subject: Re: [Tutor] Running Python Scripts at same time On 26Jun2020 11:21, John Weller wrote: >I have a Python program which will be running 24/7 (I hope ?). It is >generating data in a file which I want to clean up overnight. The way >I am looking at doing it is to run a separate program as a Cron job at >midnight ? will that work? The alternative is to add it to the loop >and check for the time. I have tried researching this but only got even >more confused. Running a separate program is perfectly reasonable. And crontab is a perfect place for a regular task like this. The primary issue usually is that you do not want both programms to be using the file at the same time. Supposing the file were, say, a CSV file to which your long running programme (A) appended data. ANd that the clean up program (B) reads the CSV file, tidies some stuff, and rewrites the CSV file. You can imagine this sequence: - programme B opens the file and reads the data - programme B thinks about the data to clean it - programme A appends more data to the file - programme B rewrites the clean data into the file, _overwriting_ the new data programme A just appended The usual process with a shared external file is to use a lock facility. These come in a few forms, and it is essential that both programme A and programme B use the same locking system. One of the easiest and most portable is to make a lock file while you work with the file. If your data file is called "foo" you might use a lock fie called "foo.lock". On a UNIX type system (includes Linux) you can atomicly make such a file like this: import os ....... lockpath = datafilepath + '.lock' lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0) That is a special mode of the OS "open" call (_not_ Python's default "open" builtin) whose parameters have the following meanings: - os.O_CREAT: create the file if missing - os.O_EXCL: ensure that the file is created - if it already exists this raises an exception - os.O_RDWR: open the file for read and write - 0: the initial permissions, ensuring that the file is _not_ readable or writable See "man 2 open" on a UNIX system for the spec. The combination of O_RDWR and 0 permissions means that if the file already exists (made by the "other" programme) then it won't have any permissions, which means we won't get read or write access and the open will fail. The nice thing about this is that the initial permissions are _immediate_ when the file is created by the OS - there's no tiny window where the file has read/write perms which then get removed - the OS ensures it. This is nice on networked file shares (if they are reliable). Anyway, the upshort of the os.open() call above is that if the lockfile already exists, the open will fail, and otherwise it will succeed, preventing antoehr programme doing the same thing. When finished, close the lockfd and remove the lock file: os.close(lockfd) os.remove(lockpath) No, because the whole scenario is that occasionally both programms want the file at the same time, the os.open _will_ fail in that case. SO the idea is that you repeat it until it succeeds, then do your work: while True: try: lockfd = os.open(lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0) except OSError as e: print("lock not obtained, sleeping") time.sleep(1) else: break .... work with the data file ... os.close(lockfd) os.remove(lockpath) Put that logic in both programmes and you should be ok. You can see a more elaborate version of this logic in my "makelockfile" function here: https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/fileutils.py#lines-527 (Atlassian are going to nuke that repo soon, alas, because they find mercurial too hard. But until then the link should be good.) Cheers, Cameron Simpson From alan.gauld at yahoo.co.uk Sun Jun 28 11:35:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 28 Jun 2020 16:35:49 +0100 Subject: [Tutor] Running Python Scripts at same time In-Reply-To: <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk> References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> <20200627230539.GA56218@cskk.homeip.net> <001901d64d32$ca6e5420$5f4afc60$@johnweller.co.uk> Message-ID: On 28/06/2020 10:59, John Weller wrote: > I am an experienced programmer new to Python and had visions > of the early interpreted languages I used such as those of> the BBC Micro and early PCs While there is a shared heritage as interpreted languages Python is part of the new breed and is far more capable than those earlier BASIC languages. It is also designed to integrate with compiled libraries from the ground up and so has accumulated a vast library that can tackle most jobs for which the highest speed is not the chief criterion. In many ways Python's structured syntax and compile-to-bytecode approach is more like UCSD Pascal that used to be available for the Beeb than it is to BBC BASIC. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sun Jun 28 11:42:13 2020 From: __peter__ at web.de (Peter Otten) Date: Sun, 28 Jun 2020 17:42:13 +0200 Subject: [Tutor] Running Python Scripts at same time References: <00bb01d64ba3$7fd471f0$7f7d55d0$@johnweller.co.uk> Message-ID: Mats Wichmann wrote: > On June 26, 2020 4:21:02 AM MDT, John Weller > wrote: >>I have a Python program which will be running 24/7 (I hope ?). It is >>generating data in a file which I want to clean up overnight. The way >>I am looking at doing it is to run a separate program as a Cron job at >>midnight ? will that work? The alternative is to add it to the loop >>and check for the time. I have tried researching this but only got even >>more confused. > a common technique is a "log rotate" one... I see it's got a wikipedia > page, take a look for some ideas. You may also consider Python's logging library which supports log rotation: https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler That way you don't need the cronjob, or, if you want to do some postprocessing, can point it to the latest backup. Locking will become a non-issue. From l2verma at uwaterloo.ca Sun Jun 28 19:18:54 2020 From: l2verma at uwaterloo.ca (Lakshay Verma) Date: Sun, 28 Jun 2020 23:18:54 +0000 Subject: [Tutor] Subplotting Figure Handles - Python Help Message-ID: Hello, I am currently working on a project whereby I collect data from a redshift database and do some analysis on it. I have made several functions that all generate figures, and output them as figure handles. For example, a function will take in query text, run the query in the database, and then I'll use pandas to store the data in a dataframe, and matplotlib to graph the data and do some statistical analysis on it. The function will then return a figure handle (
). How do I go about subplotting these figures? Because right now, I am not able to subplot them and it's really frustrating because when I save the figures to a pdf, I'm getting 20+ page pdfs whereas I would like 5 pages whereby I can group plots that analyze similar data. I'd be happy to discuss this over a video call so you can see the code and get a better idea. Thanks! Regards, Lakshay Verma Chemical Engineering Student University of Waterloo E: l2verma at edu.uwaterloo.ca P: (647) 721-8414 From manpritsinghece at gmail.com Mon Jun 29 08:35:01 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 29 Jun 2020 18:05:01 +0530 Subject: [Tutor] key parameter in sorted Message-ID: Sir, According to the python documentation,function sorted have a *key* parameter to specify a function to be called on each element prior to making comparisons. consider a case if i am using python 3.6, and i have to remove duplicates from a list, while maintaining the order of the elements, i just need to know if my solution(which is given below ) is syntactically correct and efficient or not . The result i am getting is correct and have tested it so many times . Reason for asking this question is, here i have passed method of list data type (list.index) to the key parameter of sorted function . Can i pass a method to the key parameter of sorted function ? lx = [2, 5, 4, 6, 4, 2, 3, 6] sorted(set(lx), key=lx.index) Regards Manprit Singh From __peter__ at web.de Mon Jun 29 09:46:24 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 29 Jun 2020 15:46:24 +0200 Subject: [Tutor] key parameter in sorted References: Message-ID: Manprit Singh wrote: > Sir, > According to the python documentation,function sorted > have a *key* > parameter to specify a function to be called on each element prior to > making comparisons. > > consider a case if i am using python 3.6, and i have to remove duplicates > from a list, while maintaining the order of the elements, i just need to > know if my solution(which is given below ) is syntactically correct and > efficient or not . > The result i am getting is correct and have tested it so many times . > Reason for asking this question is, here i have passed method of list > data type (list.index) to the key parameter of sorted function . Can i > pass a method to the key parameter of sorted function ? You can pass any callable object as the key parameter. > lx = [2, 5, 4, 6, 4, 2, 3, 6] > sorted(set(lx), key=lx.index) Your code is correct, but not efficient: you need up to len(lx) linear searches over the list just to calculate the key values. An alternative may be to rely on dicts preserving insertion order (officially in 3.7, but implemented in 3.6): >>> lx = [2, 5, 4, 6, 4, 2, 3, 6] >>> list(dict.fromkeys(lx)) [2, 5, 4, 6, 3] From __peter__ at web.de Mon Jun 29 09:51:46 2020 From: __peter__ at web.de (Peter Otten) Date: Mon, 29 Jun 2020 15:51:46 +0200 Subject: [Tutor] key parameter in sorted References: Message-ID: Peter Otten wrote: > Manprit Singh wrote: >> lx = [2, 5, 4, 6, 4, 2, 3, 6] >> sorted(set(lx), key=lx.index) Another option: >>> def unique(items): ... seen = set() ... for item in items: ... if item not in seen: ... yield item ... seen.add(item) ... >>> list(unique(lx)) [2, 5, 4, 6, 3] From david at lowryduda.com Mon Jun 29 10:24:18 2020 From: david at lowryduda.com (David Lowry-Duda) Date: Mon, 29 Jun 2020 10:24:18 -0400 Subject: [Tutor] Subplotting Figure Handles - Python Help In-Reply-To: References: Message-ID: <20200629142418.GA21362@icerm-dld> Hello! On Sun, Jun 28, 2020 at 11:18:54PM +0000, Lakshay Verma wrote: > Hello, > > How do I go about subplotting these figures? Because right now, I am > not able to subplot them and it's really frustrating because when I > save the figures to a pdf, I'm getting 20+ page pdfs whereas I would > like 5 pages whereby I can group plots that analyze similar data. Without seeing your code, it's hard to give specific pointers. But I suspect you'll get far if you adjust the code in some of the matplotlib examples on the matplotlib site. In particular, I think this page https://matplotlib.org/gallery/subplots_axes_and_figures/subplots_demo.html#sphx-glr-gallery-subplots-axes-and-figures-subplots-demo-py will be of interest. A similar, but condensed, presentation is on StackOverflow at https://stackoverflow.com/questions/31726643/how-do-i-get-multiple-subplots-in-matplotlib > I'd be happy to discuss this over a video call so you can see the code > and get a better idea. Thanks! This isn't something I'd be interested in. But I think if you distilled your question to a form where you could share the code on this list, it would raise the likelood both of getting any answer and an explicitly helpful answer. Finally, in case you have other matplotlib-specific questions in the future, it may be helpful to post on the matplotlib-users mailing list https://mail.python.org/mailman/listinfo/matplotlib-users Good luck! - DLD -- David Lowry-Duda From adameyring at gmail.com Mon Jun 29 10:44:26 2020 From: adameyring at gmail.com (Adam Eyring) Date: Mon, 29 Jun 2020 10:44:26 -0400 Subject: [Tutor] Subplotting Figure Handles - Python Help In-Reply-To: References: Message-ID: I'm not sure if this would help you, but you may want to check out the Bokeh package to see if it offers the plotting options you need if you get stuck on matplotlib. I like the way it does subplots. https://bokeh.org/ AME On Mon, Jun 29, 2020 at 9:25 AM Lakshay Verma wrote: > Hello, > > I am currently working on a project whereby I collect data from a redshift > database and do some analysis on it. I have made several functions that all > generate figures, and output them as figure handles. For example, a > function will take in query text, run the query in the database, and then > I'll use pandas to store the data in a dataframe, and matplotlib to graph > the data and do some statistical analysis on it. The function will then > return a figure handle (
). How do I go about > subplotting these figures? Because right now, I am not able to subplot them > and it's really frustrating because when I save the figures to a pdf, I'm > getting 20+ page pdfs whereas I would like 5 pages whereby I can group > plots that analyze similar data. I'd be happy to discuss this over a video > call so you can see the code and get a better idea. Thanks! > Regards, > > Lakshay Verma > Chemical Engineering Student > University of Waterloo > E: l2verma at edu.uwaterloo.ca > P: (647) 721-8414 > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor >