From phillor9 at gmail.com Thu Jun 1 00:15:34 2023 From: phillor9 at gmail.com (Phil) Date: Thu, 1 Jun 2023 14:15:34 +1000 Subject: [Tutor] Creating menu shortcut key bindings Message-ID: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> I've fooled around with this for several hours including extensive searching of the Internet. What I have is a file menu with open and exit options that I've created with pygubu, which works perfectly. Now I'm trying to add a shortcut key (ctl + o) to open a file. The code under 'Get a reference to the "Open" menu item widget' and 'Bind the shortcut key to the menu item' does not produce an error. So I presume that the code under "Set the accelerator property of the menu item to 'Control+O'" is the problem. My AI friend has suggested several options but they all result in an 'unknown option' error message. Can anyone see where I've gone astray? ??? def __init__(self, master=None): ??????? self.builder = builder = pygubu.Builder() ??????? builder.add_resource_path(PROJECT_PATH) ??????? builder.add_from_file(PROJECT_UI) ??????? # Main widget ??????? self.mainwindow = builder.get_object("Toplevel1", master) ??????? # Main menu ??????? _main_menu = builder.get_object("Menu1", self.mainwindow) ??????? self.mainwindow.configure(menu=_main_menu) ??????? builder.connect_callbacks(self) ??????? # Get a reference to the "Open" menu item widget ??????? open_menu_item = builder.get_object("mnu_open", _main_menu) # no error here ??????? # Set the accelerator property of the menu item to 'Control+O' # option problems here ??????? #open_menu_item['underline'] = 0#'Control+O' ??????? #open_menu_item['label'] = 'Open\tCtrl+O' ??????? #open_menu_item['']#accelerator'] = 'Ctrl+O' ??????? # Bind the shortcut key to the menu item ??????? self.mainwindow.bind('', lambda event: open_menu_item.invoke()) # no error here -- Regards, Phil From phillor9 at gmail.com Thu Jun 1 00:38:24 2023 From: phillor9 at gmail.com (Phil) Date: Thu, 1 Jun 2023 14:38:24 +1000 Subject: [Tutor] Re shortcut message - more info Message-ID: This almost works correctly. self.mainwindow.bind('', lambda event: self.open_file()) If I press 'ctl + o' nothing happens, however, if I press 'o' on it's own then the open file dialogue opens. So, I'm almost there. -- Regards, Phil From PythonList at DancesWithMice.info Thu Jun 1 01:34:06 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 1 Jun 2023 17:34:06 +1200 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: <5aaf328e-8547-b5cf-0dc6-9d42472668b8@DancesWithMice.info> On 01/06/2023 16.15, Phil wrote: > I've fooled around with this for several hours including extensive > searching of the Internet. I've never used this module/generator before and became quite interested - until I struck the problem you mentioned: little relevant documentation. Sad because "no thanks"... > What I have is a file menu with open and exit options that I've created > with pygubu, which works perfectly. Now I'm trying to add a shortcut key > (ctl + o) to open a file. tkinter has a particular way of doing things. Try: Keyboard shortcuts with Tkinter in Python 3: https://www.tutorialspoint.com/keyboard-shortcuts-with-tkinter-in-python-3 How to activate Tkinter menu and toolbar with keyboard shortcut or binding?: https://www.geeksforgeeks.org/how-to-activate-tkinter-menu-and-toolbar-with-keyboard-shortcut-or-binding/ -- Regards, =dn From phillor9 at gmail.com Thu Jun 1 02:09:30 2023 From: phillor9 at gmail.com (Phil) Date: Thu, 1 Jun 2023 16:09:30 +1000 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: <5aaf328e-8547-b5cf-0dc6-9d42472668b8@DancesWithMice.info> References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> <5aaf328e-8547-b5cf-0dc6-9d42472668b8@DancesWithMice.info> Message-ID: <2cec8dea-fa32-acd4-2173-715f79986f96@gmail.com> On 1/6/23 15:34, dn via Tutor wrote: > Thank you dn, I had already scanned through the first link but couldn't relate the information with the code I have. I'll give it a rest for today and have another look tomorrow. > tkinter has a particular way of doing things. Try: > > Keyboard shortcuts with Tkinter in Python 3: > https://www.tutorialspoint.com/keyboard-shortcuts-with-tkinter-in-python-3 > > How to activate Tkinter menu and toolbar with keyboard shortcut or > binding?: > https://www.geeksforgeeks.org/how-to-activate-tkinter-menu-and-toolbar-with-keyboard-shortcut-or-binding/ > -- Regards, Phil From bouncingcats at gmail.com Thu Jun 1 07:35:26 2023 From: bouncingcats at gmail.com (David) Date: Thu, 1 Jun 2023 11:35:26 +0000 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: On Thu, 1 Jun 2023 at 04:16, Phil wrote: > What I have is a file menu with open and exit options that I've created > with pygubu, which works perfectly. Now I'm trying to add a shortcut key > (ctl + o) to open a file. > # Bind the shortcut key to the menu item > self.mainwindow.bind('', lambda event: open_menu_item.invoke()) # no error here Hi, Your '' is what Tk calls an event sequence [1]. Your event sequence does not specify any event type [2]. Some event sequences allow the event type to be omitted for brevity. For example [3]: 'x' is the same as '' However, I suspect that what you have might not be recognised. Looking at working code I have here (without actually testing what you have) I see that I have: '' Maybe try that. [1] https://tkdocs.com/shipman/event-sequences.html [2] https://tkdocs.com/shipman/event-types.html [3] https://tkdocs.com/shipman/event-modifiers.html From alan.gauld at yahoo.co.uk Thu Jun 1 17:21:12 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 1 Jun 2023 22:21:12 +0100 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: <2cec8dea-fa32-acd4-2173-715f79986f96@gmail.com> References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> <5aaf328e-8547-b5cf-0dc6-9d42472668b8@DancesWithMice.info> <2cec8dea-fa32-acd4-2173-715f79986f96@gmail.com> Message-ID: On 01/06/2023 07:09, Phil wrote: > I had already scanned through the first link but couldn't relate the > information with the code I have. That's the problem. Your GUI builder is spitting out decidedly non-Tkinter-like code so it's hard to know how to fix it without delving into how the GUI builder works. If it was my own (conventional Tkinter style) code I'd just miss out the mainwindow bit and bind to self. But you appear to be using a Toplevel widget somewhere in the design and that might mess things up. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Thu Jun 1 17:23:34 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 1 Jun 2023 22:23:34 +0100 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: On 01/06/2023 12:35, David wrote: > Your event sequence does not specify any event type [2]. > > Some event sequences allow the event type to be omitted > for brevity. For example [3]: > 'x' is the same as '' > > However, I suspect that what you have might not be recognised. > Looking at working code I have here (without actually > testing what you have) I see that I have: > '' I have code that binds and it works OK. I suspect the widget might be the issue. But its all speculation without knowing how the GUI builder constructs things. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PythonList at DancesWithMice.info Thu Jun 1 18:14:08 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 2 Jun 2023 10:14:08 +1200 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: On 02/06/2023 09.23, Alan Gauld via Tutor wrote: > On 01/06/2023 12:35, David wrote: > >> Your event sequence does not specify any event type [2]. >> >> Some event sequences allow the event type to be omitted >> for brevity. For example [3]: >> 'x' is the same as '' >> >> However, I suspect that what you have might not be recognised. >> Looking at working code I have here (without actually >> testing what you have) I see that I have: >> '' > > I have code that binds and it works OK. > I suspect the widget might be the issue. But its all speculation > without knowing how the GUI builder constructs things. Disclaimer: My bias is to use HTML5 for multi-platform GUI. One of the short-comings in the Python world has been the lack of a GUI-generator. The major GUI-libraries are all programmer-oriented, ie building things-up by creating individual widgets fitted into wider constructs. Whereas other systems are more user-oriented and probably start with the appearance of the visual interface rather than 'what this button does' ("declarative" cf "procedural"). Considering the meaning of the "U" in "GUI", and the importance of UX (User Experience), the latter makes a lot of sense, and from a designer's PoV, makes it a lot easier to involve the user - and on the machine in 'dynamic mode' rather than on-paper or a white-board. (see also Agile approaches) Hence the OP piquing my interest! As programmers, the former suits the way we usually work (and think). The 'holy grail' of such generators is 'round-tripping': the ability to generate a GUI's code from some layout, PLUS to take existing code and use it within the generator. This enables one to operate in either/both mode(s). Unfortunately, judging from web-questions associated with this package, it appears to be less than reliable as a generator and has no ability to work from existing tk-code. -- Regards, =dn From alan.gauld at yahoo.co.uk Thu Jun 1 19:37:54 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 2 Jun 2023 00:37:54 +0100 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: On 01/06/2023 23:14, dn via Tutor wrote: > Disclaimer: My bias is to use HTML5 for multi-platform GUI. I don't like web browsers as an operating system so I still build desktop apps. But rarely do they need to be multi-platform, but if so I use Java. > One of the short-comings in the Python world has been the lack of a > GUI-generator. Agreed, I've tried several but none were entirely successful. And that goes extra for tkinter. The GTk and Qt worlds have usable tools but Tkinter and WxPython struggle. > designer's PoV, makes it a lot easier to involve the user - and on the > machine in 'dynamic mode' rather than on-paper or a white-board. (see > also Agile approaches) Yes, in my working life I've found dummy UIs to be an invaluable tool when teasing out user expectations and workflow issues. > The 'holy grail' of such generators is 'round-tripping': the ability to > generate a GUI's code from some layout, PLUS to take existing code and > use it within the generator. I've never found any GUI builder that is really capable of that. Some can work with modified code if the programmer copies the tool's own style but give them a raw app written by hand and they usually fall over in a heap! That said, if I have to develop a GUI app I use: - Delphi/Lazarus on Windows/Linux - Apple's X Developer/Swift for MacOS (sometimes with Python as the target!) - Java Swing or Fx for multi platform. (Once upon a time I'd have included SmallTalk here but my SmallTalk is too rusty now!) Tkinter is great for front-ending command-line apps or building a database browser. But for anything more sophisticated there are better tools. All IMHO of course... -- 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 PythonList at DancesWithMice.info Thu Jun 1 20:05:05 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 2 Jun 2023 12:05:05 +1200 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: (chuckling, over the @Alan/dn debating, comparing, and contrasting) On 02/06/2023 11.37, Alan Gauld via Tutor wrote: > On 01/06/2023 23:14, dn via Tutor wrote: > >> Disclaimer: My bias is to use HTML5 for multi-platform GUI. > > I don't like web browsers as an operating system so I still > build desktop apps. But rarely do they need to be multi-platform, > but if so I use Java. Heresy! >> One of the short-comings in the Python world has been the lack of a >> GUI-generator. > > Agreed, I've tried several but none were entirely successful. > And that goes extra for tkinter. The GTk and Qt worlds have > usable tools but Tkinter and WxPython struggle. With apologies, I forgot/neglected to observe that the popular GUIs, eg the three above; are *not* Python, but additional modules/libraries - although tkinter is in the PSL (?delivered with all 'desktop versions' of Python?). >> designer's PoV, makes it a lot easier to involve the user - and on the >> machine in 'dynamic mode' rather than on-paper or a white-board. (see >> also Agile approaches) > > Yes, in my working life I've found dummy UIs to be an invaluable > tool when teasing out user expectations and workflow issues. Agreed, but when it comes to "I want this in bright pink" or "can we widen that field?", there's no substitute for doing it on a 'workbench'* and enabling the user to see and think in user-mode. *and having the user say: "ooh yuk! Please put it back."! >> The 'holy grail' of such generators is 'round-tripping': the ability to >> generate a GUI's code from some layout, PLUS to take existing code and >> use it within the generator. > > I've never found any GUI builder that is really capable of that. > Some can work with modified code if the programmer copies the > tool's own style but give them a raw app written by hand and > they usually fall over in a heap! > > That said, if I have to develop a GUI app I use: > - Delphi/Lazarus on Windows/Linux > - Apple's X Developer/Swift for MacOS (sometimes with Python > as the target!) > - Java Swing or Fx for multi platform. (Once upon a time I'd > have included SmallTalk here but my SmallTalk is too rusty now!) Apologies to you if you didn't see the Delphi set-up coming. It was thoroughly remarkable in this regard! As were several of the Borland generator-tools of that era. Perhaps even the standard by which us old-f***s judge today's offerings? > Tkinter is great for front-ending command-line apps or building > a database browser. But for anything more sophisticated there > are better tools. All IMHO of course... +1 -- Regards, =dn From PythonList at DancesWithMice.info Thu Jun 1 20:10:20 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 2 Jun 2023 12:10:20 +1200 Subject: [Tutor] Late notice: Starting-out with Python Message-ID: <4c0ea821-5742-582c-5934-7d88c491bea9@DancesWithMice.info> (Assuming your time-zone) A virtual-meeting for complete newbies! Have noted that SacPy (the PUG based in Sacramento, California, United States) is holding a monthly-meeting in a few hours from now (0200 UTC). > Tonight's session is going to be a live tutorial for a complete newbie to the Python language. Meetup tells me that there are at least a dozen RSVPs that have never attended in the past, so there are at least a few of you that are wondering how to get started in Python. You're in luck, tonight is your night! https://www.meetup.com/sacramentopython/events/mptjbtyfcjbcb/ -- Regards, =dn From bouncingcats at gmail.com Fri Jun 2 05:56:51 2023 From: bouncingcats at gmail.com (David) Date: Fri, 2 Jun 2023 09:56:51 +0000 Subject: [Tutor] Creating menu shortcut key bindings In-Reply-To: References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com> Message-ID: On Thu, 1 Jun 2023 at 21:25, Alan Gauld via Tutor wrote: > On 01/06/2023 12:35, David wrote: > > > Your event sequence does not specify any event type [2]. > > > > Some event sequences allow the event type to be omitted > > for brevity. For example [3]: > > 'x' is the same as '' > > > > However, I suspect that what you have might not be recognised. > > Looking at working code I have here (without actually > > testing what you have) I see that I have: > > '' > > I have code that binds and it works OK. > I suspect the widget might be the issue. But its all speculation > without knowing how the GUI builder constructs things. Hi, You are right. I tested binding 'a' 'KeyPress-a' 'Control-a' 'Control-KeyPress-a' to button widgets and they all are responsive. A small aside regarding the 'Shift' event modifier: 'Shift-Keypress-a' does not work. 'Keypress-A' is required for that. I assume that is only a consideration for alphabetic keys, because 'Shift-KeyPress-space' is responsive. I understand that I am ignoring the 'pygubu' that Phil is using, so my input to the conversation is probably not of much use. Even so, I have one more point that I noticed during testing, that is worth stating explicitly on the chance that it might help Phil: If event sequences are bound to a particular widget 'w', then they will only be responsive when widget 'w' has the keyboard focus, otherwise they are completely ignored. So when I see that Phil's code does: self.mainwindow.bind('', ... it makes me wonder: 1) if self.mainwindow is the appropriate widget to bind to 2) if self.mainwindow has the keyboard focus at the time of the event My final suggestion is to ask the tkinter mailing list: https://mail.python.org/mailman/listinfo/tkinter-discuss It is low traffic, but responsive. From trent.shipley at gmail.com Tue Jun 6 00:58:56 2023 From: trent.shipley at gmail.com (trent shipley) Date: Mon, 5 Jun 2023 21:58:56 -0700 Subject: [Tutor] Feed arguments to callback(?) function Message-ID: I want to take and arbitrary probability distribution function, send it it's keyword arguments, and run it as the core of a generic dice rolling program in Python (so it is accessible to the maximum number of programmers), # hackable_dice_roller # from typing import Any, List, Tuple, Callable from random import normalvariate, randrange, seed # import operator class DieRoll: def __init__(self, die, # a probability input function transform=None, # a function to transform the result returned by the PDF **die_args): # Keyword:Value arguments to the PDF python function (doesn't work) self._die = die self._transform = transform self._die_args = die_args def die_roll(self): roll = self._die(self._die_args) # throws error if self._transform is not None: roll = self._transform(roll) return roll class IntegerDieRoll(DieRoll): def __init__(self, transform=None, sides=6, bottom=1): super().__init__(die=randrange, # a random module pdf transform=transform, start=bottom, # say 1 on a 6 sided die stop=bottom + sides, # 1 + 6 = 7, randrange should return value 1 to 6 inclusive step=1) if sides <= 0: raise ValueError("Parameter 'die' must be at least 1") def die_roll(self): return int(super().die_roll()) if __name__ == '__main__': seed(0) integer_die_roll = IntegerDieRoll() print(integer_die_roll.die_roll()) ---------- Traceback (most recent call last): File "/usr/lib/python3.11/random.py", line 295, in randrange istart = _index(start) ^^^^^^^^^^^^^ TypeError: 'dict_values' object cannot be interpreted as an integer During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", line 85, in print(integer_die_roll.die_roll()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", line 41, in die_roll return int(super().die_roll()) ^^^^^^^^^^^^^^^^^^ File "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", line 21, in die_roll roll = self._die(self._die_args.values()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/random.py", line 297, in randrange istart = int(start) ^^^^^^^^^^ TypeError: int() argument must be a string, a bytes-like object or a real number, not 'dict_values' Process finished with exit code 1 From sarfraaz at gmail.com Tue Jun 6 07:18:58 2023 From: sarfraaz at gmail.com (Sarfraaz Ahmed) Date: Tue, 6 Jun 2023 16:48:58 +0530 Subject: [Tutor] Feed arguments to callback(?) function In-Reply-To: References: Message-ID: I think you have to unpack the dictionary using ** while passing it as a bunch of arguments to the transform function roll = self._die(**self._die_args) # added ** On Tue, Jun 6, 2023 at 1:35?PM trent shipley wrote: > I want to take and arbitrary probability distribution function, send it > it's keyword arguments, and run it as the core of a generic dice rolling > program in Python (so it is accessible to the maximum number of > programmers), > > > # hackable_dice_roller > # from typing import Any, List, Tuple, Callable > from random import normalvariate, randrange, seed > # import operator > > > class DieRoll: > def __init__(self, > die, # a probability input function > transform=None, # a function to transform the result > returned by the PDF > **die_args): # Keyword:Value arguments to the PDF python > function (doesn't work) > self._die = die > self._transform = transform > self._die_args = die_args > > def die_roll(self): > roll = self._die(self._die_args) # throws error > if self._transform is not None: > roll = self._transform(roll) > return roll > > > class IntegerDieRoll(DieRoll): > def __init__(self, > transform=None, > sides=6, > bottom=1): > super().__init__(die=randrange, # a random module pdf > transform=transform, > start=bottom, # say 1 on a 6 sided die > stop=bottom + sides, # 1 + 6 = 7, randrange > should return value 1 to 6 inclusive > step=1) > if sides <= 0: > raise ValueError("Parameter 'die' must be at least 1") > > def die_roll(self): > return int(super().die_roll()) > > if __name__ == '__main__': > seed(0) > > integer_die_roll = IntegerDieRoll() > print(integer_die_roll.die_roll()) > > ---------- > > Traceback (most recent call last): > File "/usr/lib/python3.11/random.py", line 295, in randrange > istart = _index(start) > ^^^^^^^^^^^^^ > TypeError: 'dict_values' object cannot be interpreted as an integer > > During handling of the above exception, another exception occurred: > > Traceback (most recent call last): > File > "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", > line 85, in > print(integer_die_roll.die_roll()) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File > "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", > line 41, in die_roll > return int(super().die_roll()) > ^^^^^^^^^^^^^^^^^^ > File > "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", > line 21, in die_roll > roll = self._die(self._die_args.values()) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/usr/lib/python3.11/random.py", line 297, in randrange > istart = int(start) > ^^^^^^^^^^ > TypeError: int() argument must be a string, a bytes-like object or a real > number, not 'dict_values' > > 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 > -- Jazaak Allahu Khair -- Sarfraaz Ahmed From trent.shipley at gmail.com Wed Jun 7 14:09:15 2023 From: trent.shipley at gmail.com (trent shipley) Date: Wed, 7 Jun 2023 11:09:15 -0700 Subject: [Tutor] Feed arguments to callback(?) function In-Reply-To: References: Message-ID: Yes that was exactly it. Another problem is that Python doesn't like you trying to pass in arbitrary keyword arguments instead because it could result in a name collision, so using *args is preferred. I found this to be very helpful: https://www.informit.com/articles/article.aspx?p=3145749&seqNum=16 On Tue, Jun 6, 2023 at 4:19?AM Sarfraaz Ahmed wrote: > I think you have to unpack the dictionary using ** while passing it as a > bunch of arguments to the transform function > > roll = self._die(**self._die_args) # added ** > > On Tue, Jun 6, 2023 at 1:35?PM trent shipley > wrote: > >> I want to take and arbitrary probability distribution function, send it >> it's keyword arguments, and run it as the core of a generic dice rolling >> program in Python (so it is accessible to the maximum number of >> programmers), >> >> >> # hackable_dice_roller >> # from typing import Any, List, Tuple, Callable >> from random import normalvariate, randrange, seed >> # import operator >> >> >> class DieRoll: >> def __init__(self, >> die, # a probability input function >> transform=None, # a function to transform the result >> returned by the PDF >> **die_args): # Keyword:Value arguments to the PDF python >> function (doesn't work) >> self._die = die >> self._transform = transform >> self._die_args = die_args >> >> def die_roll(self): >> roll = self._die(self._die_args) # throws error >> if self._transform is not None: >> roll = self._transform(roll) >> return roll >> >> >> class IntegerDieRoll(DieRoll): >> def __init__(self, >> transform=None, >> sides=6, >> bottom=1): >> super().__init__(die=randrange, # a random module pdf >> transform=transform, >> start=bottom, # say 1 on a 6 sided die >> stop=bottom + sides, # 1 + 6 = 7, randrange >> should return value 1 to 6 inclusive >> step=1) >> if sides <= 0: >> raise ValueError("Parameter 'die' must be at least 1") >> >> def die_roll(self): >> return int(super().die_roll()) >> >> if __name__ == '__main__': >> seed(0) >> >> integer_die_roll = IntegerDieRoll() >> print(integer_die_roll.die_roll()) >> >> ---------- >> >> Traceback (most recent call last): >> File "/usr/lib/python3.11/random.py", line 295, in randrange >> istart = _index(start) >> ^^^^^^^^^^^^^ >> TypeError: 'dict_values' object cannot be interpreted as an integer >> >> During handling of the above exception, another exception occurred: >> >> Traceback (most recent call last): >> File >> "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", >> line 85, in >> print(integer_die_roll.die_roll()) >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> File >> "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", >> line 41, in die_roll >> return int(super().die_roll()) >> ^^^^^^^^^^^^^^^^^^ >> File >> "/home/trent/pythonworkspace/hackable_dice_roller/roll_instruction.py", >> line 21, in die_roll >> roll = self._die(self._die_args.values()) >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> File "/usr/lib/python3.11/random.py", line 297, in randrange >> istart = int(start) >> ^^^^^^^^^^ >> TypeError: int() argument must be a string, a bytes-like object or a real >> number, not 'dict_values' >> >> 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 >> > > > -- > Jazaak Allahu Khair > -- Sarfraaz Ahmed > From trent.shipley at gmail.com Wed Jun 7 15:54:30 2023 From: trent.shipley at gmail.com (trent shipley) Date: Wed, 7 Jun 2023 12:54:30 -0700 Subject: [Tutor] Testing a dice roller project Message-ID: I had only done programming for: - class assignments - for scratching little itches at work - occasional very small work assignments - (and a respectable amount of SQL at work, if you count that), but for the first time I have finished my first draft of a self-motivated project. It is only the core logic of a little dice rolling utility motivated by not finding The Perfect RPG Dice Roller, but I am inordinately proud of it. I still need to add a little core functionality, do the drudgery of testing, and add a command line interface and more testing, an RPG GUI and its testing, and a scientific GUI and testing for it. 1. What options are available for unit testing Python code? What are the pros and cons? 2. Where can I find style guides and pointers for Python documentation? 3. When should I put it on my GitHub account? 4. I *need* feedback and code review. How do I solicit (or shop and pay for) feedback? 5. Is there an active list where it would be more appropriate to ask the many questions I have since they are not absolute beginner questions? (Lite intermediate_tutor at python.org.) From PythonList at DancesWithMice.info Wed Jun 7 18:55:46 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 8 Jun 2023 10:55:46 +1200 Subject: [Tutor] Testing a dice roller project In-Reply-To: References: Message-ID: <7db7538f-e441-b50b-c6b7-cbf4d8f6a1e3@DancesWithMice.info> On 08/06/2023 07.54, trent shipley wrote: > I had only done programming for: > > - class assignments > - for scratching little itches at work > - occasional very small work assignments > - (and a respectable amount of SQL at work, if you count that), Well done! > but for the first time I have finished my first draft of a self-motivated > project. It is only the core logic of a little dice rolling utility > motivated by not finding The Perfect RPG Dice Roller, but I am inordinately > proud of it. I still need to add a little core functionality, do the > drudgery of testing, and add a command line interface and more testing, an > RPG GUI and its testing, and a scientific GUI and testing for it. but ? drudgery - making sure that it actually works - before inviting others to use it and form your reputation? > 1. What options are available for unit testing Python code? What are the > pros and cons? unittest - in the PSL pytest - preference (IMHO) hypothesis - advanced but powerful (saves 'drudgery', yields 'surprises') > 2. Where can I find style guides and pointers for Python documentation? PEP-008 https://documentation.divio.com/ > 3. When should I put it on my GitHub account? Never - unless you want MSFT to own it, and use it for their own purposes without your active permission and without attribution, respect for copyright, etc. Use GitLab or one of the other alternatives. Use other media to 'advertise'. > 4. I *need* feedback and code review. How do I solicit (or shop and pay > for) feedback? Do more homework to see that others (including several Python (and other) books) have tackled such simulations. Join your local PUG (Python Users' Group) - many of which are now meeting in virtual/hybrid mode and thus don't need to be more local than a time-zone 'close by'. > 5. Is there an active list where it would be more appropriate to ask the > many questions I have since they are not absolute beginner questions? > (Lite intermediate_tutor at python.org.) [No. My understanding is that] this list does not limit the 'level' of question. Indeed tutors have been known to ask each-other 'advanced level' questions here! -- Regards, =dn From sarfraaz at gmail.com Wed Jun 7 23:54:58 2023 From: sarfraaz at gmail.com (Sarfraaz Ahmed) Date: Thu, 8 Jun 2023 09:24:58 +0530 Subject: [Tutor] Feed arguments to callback(?) function In-Reply-To: References: Message-ID: On Wed, Jun 7, 2023 at 11:39?PM trent shipley wrote: > Yes that was exactly it. Another problem is that Python doesn't like you > trying to pass in arbitrary keyword arguments instead because it could > result in a name collision, so using *args is preferred. > > I found this to be very helpful: > https://www.informit.com/articles/article.aspx?p=3145749&seqNum=16 > > Glad to know that it helped. Continuing on the keyword arguments comment. From the same author ( Dave ), you could consider one more point where he mentions under section "Prefer keyword arguments for optional arguments" in https://dabeaz-course.github.io/practical-python/Notes/03_Program_organization/02_More_functions.html -- Jazaak Allahu Khair -- Sarfraaz Ahmed From alan.gauld at yahoo.co.uk Thu Jun 8 03:44:29 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 8 Jun 2023 08:44:29 +0100 Subject: [Tutor] Testing a dice roller project In-Reply-To: <7db7538f-e441-b50b-c6b7-cbf4d8f6a1e3@DancesWithMice.info> References: <7db7538f-e441-b50b-c6b7-cbf4d8f6a1e3@DancesWithMice.info> Message-ID: On 07/06/2023 23:55, dn via Tutor wrote: >> 5. Is there an active list where it would be more appropriate to ask the >> many questions I have since they are not absolute beginner questions? >> (Lite intermediate_tutor at python.org.) > > [No. My understanding is that] this list does not limit the 'level' of > question. Indeed tutors have been known to ask each-other 'advanced > level' questions here! That is correct. Our remit is to help new Python programmers with - Python language issues - standard library issues - general programming issues But there is no specification for how deep those issues go! But in practice there will come a time (especially if you delve into the Python innards) where we would refer you to the main Python list. -- Alan G List moderator From mk1853387 at gmail.com Thu Jun 8 15:46:59 2023 From: mk1853387 at gmail.com (marc nicole) Date: Thu, 8 Jun 2023 21:46:59 +0200 Subject: [Tutor] cubes library docs are not accurate, first example failing unexpectedly Message-ID: Hello to All, I want to create a cube from csv data file and to perform and aggregation on it, the code is below: from sqlalchemy import create_enginefrom cubes.tutorial.sql import create_table_from_csvfrom cubes import Workspace, Cell, browser import dataif __name__ == '__main__': engine = create_engine('sqlite:///data.sqlite') create_table_from_csv(engine, "../data/data.csv", table_name="irbd_balance", fields=[ ("category", "string"), ("category_label", "string"), ("subcategory", "string"), ("subcategory_label", "string"), ("line_item", "string"), ("year", "integer"), ("amount", "integer")], create_id=True ) print("done. file data.sqlite created") workspace = Workspace() workspace.register_default_store("sql", url="sqlite:///data.sqlite") workspace.import_model("../model.json") cube = workspace.cube("irbd_balance") browser = workspace.browser("irbd_balance") cell = Cell(cube) result = browser.aggregate(cell, drilldown=["year"]) for record in result.drilldown: print(record) The tutorial and the library are available here: https://pythonhosted.org/cubes/tutorial.html The error stack is : result = browser.aggregate(cell, drilldown=["year"]) File "C:\Users\path\venv\lib\site-packages\cubes\browser.py", line 145, in aggregate result = self.provide_aggregate(cell, File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line 400, in provide_aggregate (statement, labels) = self.aggregation_statement(cell, File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line 532, in aggregation_statement raise ArgumentError("List of aggregates should not be empty") cubes.errors.ArgumentError: List of aggregates should not be empty It seems the tutorial is containing some typos. Any idea how to fix this? Else is there any other better olap cubes library for Python that has great docs? From threesomequarks at proton.me Thu Jun 8 17:20:22 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Thu, 08 Jun 2023 21:20:22 +0000 Subject: [Tutor] cubes library docs are not accurate, first example failing unexpectedly In-Reply-To: References: Message-ID: As a personal observation, Marc, your code contains lots of stuff above basic Python with use of various library functions. It becomes harder to know what exactly you want. Could you explain what you mean by a "cube" for example? This line does not make it clear except that the module you are using lets you make a "cube" from whatever the workspace is you created earlier. cube = workspace.cube("irbd_balance") So at the very least, please include what you expected as compared to what you got and some hint of what the data being received looked like. Did you get error messages or just the wrong output, or perhaps a problem downstream with the remaining code you show. Of course, someone else here with experience in what you are using and doing may be able to answer. I can only ask for more info before making any suggestion. Q Sent with Proton Mail secure email. ------- Original Message ------- On Thursday, June 8th, 2023 at 3:46 PM, marc nicole wrote: > Hello to All, > > I want to create a cube from csv data file and to perform and aggregation > on it, the code is below: > > from sqlalchemy import create_enginefrom cubes.tutorial.sql import > create_table_from_csvfrom cubes import Workspace, Cell, browser > import dataif name == 'main': > engine = create_engine('sqlite:///data.sqlite') > create_table_from_csv(engine, > "../data/data.csv", > table_name="irbd_balance", > fields=[ > ("category", "string"), > ("category_label", "string"), > ("subcategory", "string"), > ("subcategory_label", "string"), > ("line_item", "string"), > ("year", "integer"), > ("amount", "integer")], > create_id=True > ) > print("done. file data.sqlite created") > workspace = Workspace() > workspace.register_default_store("sql", url="sqlite:///data.sqlite") > workspace.import_model("../model.json") > > > cube = workspace.cube("irbd_balance") > > browser = workspace.browser("irbd_balance") > > cell = Cell(cube) > result = browser.aggregate(cell, drilldown=["year"]) > for record in result.drilldown: > print(record) > > > > > > The tutorial and the library are available here: > > https://pythonhosted.org/cubes/tutorial.html > The error stack is : > > > result = browser.aggregate(cell, drilldown=["year"]) > File "C:\Users\path\venv\lib\site-packages\cubes\browser.py", line > 145, in aggregate > result = self.provide_aggregate(cell, > File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line > 400, in provide_aggregate > (statement, labels) = self.aggregation_statement(cell, > File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line > 532, in aggregation_statement > raise ArgumentError("List of aggregates should not be empty") > cubes.errors.ArgumentError: List of aggregates should not be empty > > It seems the tutorial is containing some typos. > > Any idea how to fix this? Else is there any other better olap cubes > library for Python that has great docs? > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From threesomequarks at proton.me Thu Jun 8 19:14:01 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Thu, 08 Jun 2023 23:14:01 +0000 Subject: [Tutor] cubes library docs are not accurate, first example failing unexpectedly In-Reply-To: References: Message-ID: Marc, I had noticed you posted more, including the tutorial, to the main python group. The tutorial does have typo's. I am wondering if what you want to do might be done using other methods if this is not working as expected. If the data is not too large and can be read in completely, some may place the columns wanted into a multi-dimensional construct that can also be accessed in various ways. The numpy and perhaps pandas modules can be useful or perhaps the more native matrix and array object types. Your error messages seem to suggest something you are doing is returning nothing as in a list of whatever aggregates are. Have you checked if the data coming in is what was expected and perhaps if it is maintained in subsequent steps before the error? I also note a search suggests OLAP Cubes are a bit outdated for some purposes. So rather than just looking for a specific toolset, perhaps look at what you want to do with the data first and see what other tools provide the kind of functionality needed just for the job. If it become a whole production that needs to be fast and so on, then ... Good luck. Sent with Proton Mail secure email. ------- Original Message ------- On Thursday, June 8th, 2023 at 5:20 PM, ThreeBlindQuarks via Tutor wrote: > As a personal observation, Marc, your code contains lots of stuff above basic Python with use of various library functions. It becomes harder to know what exactly you want. > > Could you explain what you mean by a "cube" for example? > > This line does not make it clear except that the module you are using lets you make a "cube" from whatever the workspace is you created earlier. > > cube = workspace.cube("irbd_balance") > > So at the very least, please include what you expected as compared to what you got and some hint of what the data being received looked like. Did you get error messages or just the wrong output, or perhaps a problem downstream with the remaining code you show. > > Of course, someone else here with experience in what you are using and doing may be able to answer. I can only ask for more info before making any suggestion. > > Q > > > > Sent with Proton Mail secure email. > > > ------- Original Message ------- > On Thursday, June 8th, 2023 at 3:46 PM, marc nicole mk1853387 at gmail.com wrote: > > > > > Hello to All, > > > > I want to create a cube from csv data file and to perform and aggregation > > on it, the code is below: > > > > from sqlalchemy import create_enginefrom cubes.tutorial.sql import > > create_table_from_csvfrom cubes import Workspace, Cell, browser > > import dataif name == 'main': > > engine = create_engine('sqlite:///data.sqlite') > > create_table_from_csv(engine, > > "../data/data.csv", > > table_name="irbd_balance", > > fields=[ > > ("category", "string"), > > ("category_label", "string"), > > ("subcategory", "string"), > > ("subcategory_label", "string"), > > ("line_item", "string"), > > ("year", "integer"), > > ("amount", "integer")], > > create_id=True > > ) > > print("done. file data.sqlite created") > > workspace = Workspace() > > workspace.register_default_store("sql", url="sqlite:///data.sqlite") > > workspace.import_model("../model.json") > > > > cube = workspace.cube("irbd_balance") > > > > browser = workspace.browser("irbd_balance") > > > > cell = Cell(cube) > > result = browser.aggregate(cell, drilldown=["year"]) > > for record in result.drilldown: > > print(record) > > > > The tutorial and the library are available here: > > > > https://pythonhosted.org/cubes/tutorial.html > > The error stack is : > > > > result = browser.aggregate(cell, drilldown=["year"]) > > File "C:\Users\path\venv\lib\site-packages\cubes\browser.py", line > > 145, in aggregate > > result = self.provide_aggregate(cell, > > File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line > > 400, in provide_aggregate > > (statement, labels) = self.aggregation_statement(cell, > > File "C:\path\venv\lib\site-packages\cubes\sql\browser.py", line > > 532, in aggregation_statement > > raise ArgumentError("List of aggregates should not be empty") > > cubes.errors.ArgumentError: List of aggregates should not be empty > > > > It seems the tutorial is containing some typos. > > > > Any idea how to fix this? Else is there any other better olap cubes > > library for Python that has great docs? > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Thu Jun 8 20:12:06 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 9 Jun 2023 01:12:06 +0100 Subject: [Tutor] cubes library docs are not accurate, first example failing unexpectedly In-Reply-To: References: Message-ID: On 08/06/2023 20:46, marc nicole wrote: > Hello to All, > > I want to create a cube from csv data file and to perform and aggregation > on it, the code is below: > > from sqlalchemy import create_enginefrom cubes.tutorial.sql import > create_table_from_csvfrom cubes import Workspace, Cell, browser Note that most of that is a) badly formatted, so it's hard to read, please post in plain text... b) not from the standard library which is the remit of this list While you might get lucky and find a cubes user on this list, you are probably better off asking on a cubes-using forum (such as SciPy?) > It seems the tutorial is containing some typos. Much open source software has low quality documentation. One of the things you pay for with commercial software is the employment of professional technical authors. If something gets popular enough some volunteer author(s) may rework the open source docs. I have no idea what status cubes is at... -- 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 baigazmat29 at gmail.com Sat Jun 10 15:08:07 2023 From: baigazmat29 at gmail.com (Azmat Ullah Baig) Date: Sun, 11 Jun 2023 00:08:07 +0500 Subject: [Tutor] Learn Python Message-ID: Respected sir, I want to become python expert but I dont have any knowledge about it. How can you help me? Thanks & Regards Azmat From mats at wichmann.us Sat Jun 10 18:14:34 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 10 Jun 2023 16:14:34 -0600 Subject: [Tutor] Learn Python In-Reply-To: References: Message-ID: On 6/10/23 13:08, Azmat Ullah Baig wrote: > Respected sir, > > I want to become python expert but I dont have any knowledge about it. How > can you help me? The answer is, you work through tutorials, work on projects of your choosing, just generally try things out - and when things are confusing, ask questions here and we'll try to help you through those issues. When you do ask questions, make sure to include enough details that people can help you; give us code snippets, error messages from when things don't work, etc. (for both code and errors, paste the text into your email, the mailing list doesn't let attachments go through for security reasons) From alan.gauld at yahoo.co.uk Sun Jun 11 13:15:05 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 11 Jun 2023 18:15:05 +0100 Subject: [Tutor] Learn Python In-Reply-To: References: Message-ID: On 10/06/2023 20:08, Azmat Ullah Baig wrote: > I want to become python expert but I dont have any knowledge about it. How > can you help me? To become an expert in anything takes a lot of time and effort. It also depends on where you start. Can you already program in another language? - Basic, Java, Javascript, Lisp etc? That will make the basic concepts in Python much easier to learn. If not, you need to learn the ideas behind programming as well as how Python implements those concepts. For example most programs consist of a few basic structures: - sequences of individual instructions or commands - repeated groups of instructions (aka loops) - optional instructions selected by some condition(aka branching or selection) The idea of selecting introduces a whole bunch of new ideas around the concept of logic, and in particular, binary (aka boolean) logic. Other topics to consider are data structures(lists, sets, dictionaries etc) and how to read data (from users, files, database, networks etc) and how to store it again. Also how to present data to the user(GUI, web page, terminal, printer etc) So there is a lot of ground to cover, but most of the ideas are the same regardless of programming language, you just need to know how your chosen language "spells" those ideas. The good news is that none of these concepts is that difficult to grasp, it is just that there are a lot of them. And computers are very unforgiving of mistakes, so spelling a word wrong, or getting the punctuation just slightly out will result in an error. The more code you write the easier it becomes. Meantime, we are here to answer questions, explain concepts that you might find difficult, help resolve errors etc. When you do ask questions be sure to be as specific as possible. Include the code, any error messages and sample output if the data seems "wrong". Post in plain text because code formatting is critically important in Python. And don't send screenshots because the server strips them as potential security issues. Cut n paste code. Finally, don't rely on AI tools(like chatGPT). These are useful when you know enough to evaluate the answer, but they can be misleading (and even flat out wrong) if you take them at face value. So, find yourself a training course/tutorial, make a start and ask questions here. Enjoy the ride. A good place to pick a tutorial is here: http://wiki.python.org/moin/BeginnersGuide It has links to lists of tutorials for both existing programmers (in other languages) or complete beginners with no programming experience. Or you could try mine :-) (see below) -- 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 goranikac65 at gmail.com Sun Jun 11 13:52:42 2023 From: goranikac65 at gmail.com (Goran Ikac) Date: Sun, 11 Jun 2023 19:52:42 +0200 Subject: [Tutor] Learn Python Message-ID: I'm a newbie in Python, too. A year ago, I started from zero, and I collected some bad, but much more nice experiences.Bad first: there are many (much too many) web sites offering Python tutorials for beginners, most of them for free. Be careful! Some of them are not worth your time, some are didactically bad, some are actually dead (no response to your questions or progress) but still expecting money for a certificate at the end of the course (not much money, thrue, but I dislike to be tricked that way). Now nice: ? Once I discovered the book "Practical Programming" 3rd Ed (Gries, Campbell & Montojo 2017) , I actually started to learn effectively. ? On the site https://realpython.com/ I found a lot of good lessons and advice. Most of their material is not free, but everything you need to start learning is free. The team working on site takes its job very seriously, they are very professional and I honestly recommend a visit. ? There is a guy, Trey Hunner, helping a lot not to lose a right way in the Pythonic jungle. You'll soon learn that "There should be one - and preferably only one - obvious way to do it." (The Zen of Python by Tim Peters) simply doesn't hold the ground in Python, so Trey's advice will be of much help. Google! ? Once you start writing some code, you'll have some real questions for the old wolves at "Tutor Digest". Then ask, and - in my experience - they will put some serious time and effort into answering. And one from my humble opinion: learn basis, learn syntax, but remember that all the books and tutorials for the newbies base their lessons on functional programming. However, it seems that the object oriented approach is the skill we need to master before we can say we know anything actually. Once, we all shall need to learn OOP! Finally, practice, practice, practice, and don't lose faith! Good luck, and happy pythonning! Goran from Croatia From adrian.mowrey at gmail.com Mon Jun 12 12:05:17 2023 From: adrian.mowrey at gmail.com (Adrian Mowrey) Date: Mon, 12 Jun 2023 19:05:17 +0300 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: References: Message-ID: Udemy, Coursera, etc. have the best courses on Python! Udemy charges, but Coursera, edX, etc. offer them for free. I also enjoyed the freeCodeCamp on YouTube! -- Thanks, Adrian On Mon, Jun 12, 2023 at 7:01?PM 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: Learn Python (Alan Gauld) > 2. Re: Learn Python (Goran Ikac) > > > > ---------- Forwarded message ---------- > From: Alan Gauld > To: tutor at python.org > Cc: > Bcc: > Date: Sun, 11 Jun 2023 18:15:05 +0100 > Subject: Re: [Tutor] Learn Python > On 10/06/2023 20:08, Azmat Ullah Baig wrote: > > I want to become python expert but I dont have any knowledge about it. > How > > can you help me? > > To become an expert in anything takes a lot of time and effort. > It also depends on where you start. > Can you already program in another language? > - Basic, Java, Javascript, Lisp etc? > That will make the basic concepts in Python much easier to learn. > > If not, you need to learn the ideas behind programming as well as > how Python implements those concepts. For example most programs > consist of a few basic structures: > - sequences of individual instructions or commands > - repeated groups of instructions (aka loops) > - optional instructions selected by some condition(aka branching > or selection) > > The idea of selecting introduces a whole bunch of new ideas > around the concept of logic, and in particular, binary > (aka boolean) logic. > > Other topics to consider are data structures(lists, sets, > dictionaries etc) and how to read data (from users, files, > database, networks etc) and how to store it again. > Also how to present data to the user(GUI, web page, terminal, > printer etc) > > So there is a lot of ground to cover, but most of the ideas are the same > regardless of programming language, you just need to know how your > chosen language "spells" those ideas. The good news is that none of > these concepts is that difficult to grasp, it is just that there are a > lot of them. And computers are very unforgiving of mistakes, so spelling > a word wrong, or getting the punctuation just slightly out will result > in an error. > > The more code you write the easier it becomes. > Meantime, we are here to answer questions, explain concepts > that you might find difficult, help resolve errors etc. > > When you do ask questions be sure to be as specific as possible. > Include the code, any error messages and sample output if the data > seems "wrong". Post in plain text because code formatting is critically > important in Python. And don't send screenshots because the server > strips them as potential security issues. Cut n paste code. > > Finally, don't rely on AI tools(like chatGPT). These are useful > when you know enough to evaluate the answer, but they can be > misleading (and even flat out wrong) if you take them at face value. > > So, find yourself a training course/tutorial, make a start and ask > questions here. Enjoy the ride. > > A good place to pick a tutorial is here: > > http://wiki.python.org/moin/BeginnersGuide > It has links to lists of tutorials for both existing programmers (in > other languages) or complete beginners with no programming experience. > > > Or you could try mine :-) > (see below) > > > > -- > 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: Goran Ikac > To: tutor at python.org > Cc: > Bcc: > Date: Sun, 11 Jun 2023 19:52:42 +0200 > Subject: Re: [Tutor] Learn Python > I'm a newbie in Python, too. A year ago, I started from zero, and I > collected some bad, but much more nice experiences.Bad first: there are > many (much too many) web sites offering Python tutorials for beginners, > most of them for free. Be careful! Some of them are not worth your time, > some are didactically bad, some are actually dead (no response to your > questions or progress) but still expecting money for a certificate at the > end of the course (not much money, thrue, but I dislike to be tricked that > way). > Now nice: > ? Once I discovered the book "Practical Programming" 3rd Ed (Gries, > Campbell & Montojo 2017) , I actually started to learn effectively. > ? On the site https://realpython.com/ I found a lot of good lessons and > advice. Most of their material is not free, but everything you need to > start learning is free. The team working on site takes its job very > seriously, they are very professional and I honestly recommend a visit. > ? There is a guy, Trey Hunner, helping a lot not to lose a right way in > the Pythonic jungle. You'll soon learn that "There should be one - and > preferably only one - obvious way to do it." (The Zen of Python by Tim > Peters) simply doesn't hold the ground in Python, so Trey's advice will be > of much help. Google! > ? Once you start writing some code, you'll have some real questions for > the old wolves at "Tutor Digest". Then ask, and - in my experience - they > will put some serious time and effort into answering. > And one from my humble opinion: learn basis, learn syntax, but remember > that all the books and tutorials for the newbies base their lessons on > functional programming. However, it seems that the object oriented approach > is the skill we need to master before we can say we know anything actually. > Once, we all shall need to learn OOP! > Finally, practice, practice, practice, and don't lose faith! > Good luck, and happy pythonning! > Goran from Croatia > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > From mats at wichmann.us Tue Jun 13 14:28:07 2023 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 13 Jun 2023 12:28:07 -0600 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: References: Message-ID: On 6/12/23 10:05, Adrian Mowrey wrote: > Udemy, Coursera, etc. have the best courses on Python! > Udemy charges, but Coursera, edX, etc. offer them for free. > > I also enjoyed the freeCodeCamp on YouTube! There are also University-type courses for free (MIT, for example). These are often woven into a larger framework - Learning Computer Science with Python. And many people these days are picking up Python not to have a general-purpose language in their toolbox, but to accomplish something particular, and there is of course courseware that caters to that - "Python for Data Scientists", "Machine Learning with Python", etc. One of the real problems when there are too many offerings is finding one that is (a) any good and (b) fits your learning style - which usually eliminate many of the ones from (a). As just an example, as a purely personal thing, I absolutely can't stand serious learning that is gamified - badges, bling, scoreboards, flashing achievements, that kind of stuff. To the point that if I try to follow a learning path which is done that way (and it's all the rage these days), I just quit it. I'm sure that's unlike the vast majority of people, or it wouldn't be such a popular style. We don't have a good way to collect or convey that information, so it's down to anecdotal information - someone here has tried something and liked it. The Python wiki is all user contributed, and it's not really curated (occasionally someone goes through and wipes out obsolete or incorrect stuff, but it's not a formal process). Be nice if we could do a bit better here on tutor, but I, at least, don't see a way (Alan?). From alan.gauld at yahoo.co.uk Tue Jun 13 17:44:19 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 13 Jun 2023 22:44:19 +0100 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: References: Message-ID: On 13/06/2023 19:28, Mats Wichmann wrote: > One of the real problems when there are too many offerings is finding > one that is (a) any good and (b) fits your learning style ... > Be nice if we could do a bit better here on tutor, but I, at least, > don't see a way (Alan?). I don't think it's possible. As you say, there are different learning styles. One person's good tutorial is the next person's nightmare. My own tutorial is aimed at a very specific type of learner; namely one who wants to learn to program, but is already quite experienced around computers - more than a casual web browser, social media jockey etc. It suits those from that user-base who want a "serious" tutorial. But if they want games, medals and flags it's not going to work for them. Other tutorials target those who just want to learn Python for a specific purpose, but that could be as trivial as writing macros for some application(Gimp say, or vim) to doing advanced science or data analysis at university research level. I honestly don't think there is any way to categorize tutorials for something as general as Python that would be useful to all. -- 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 brett at hiteklolife.net Wed Jun 14 08:04:10 2023 From: brett at hiteklolife.net (Brett C.) Date: Wed, 14 Jun 2023 22:04:10 +1000 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: References: Message-ID: <377dc274-37ff-eaa5-c44e-572464949006@hiteklolife.net> Hi, long time lurker, first time ...replier. @Azmat I don't consider myself an python "expert" but I've had some success with it and it's now a very valuable tool in my toolbox.? I come from a background in system administration, so I knew a little bit of scripting. When I started out learning I really just played with it and tried to see what I could do - I think my first project was just scraping my local weather meteorology website and reformatting the data into a table that looked cool in my Linux terminal. Python was the first language that really 'clicked' for me. Like most tools, once you get some familiarity with it, you'll start seeing how it can be used to solve problems for you. One of my first "major" projects was from when I was playing a video game called Elite Dangerous with a bunch of people I met online - everyone was recording their contributions to the group's objectives using spreadsheets and notepad and I thought to myself "there''s got to be a better way". I found that there was a log file that the game produced that I could interrogate automatically to compile all that information. It might sound silly and I'm sure to some of the people on this list, really basic, but I learned so much from that project - how to tail a file, record markers so that my program would remember where it left off if it was closed and opened again, writing a graphical user interface, subprocessing and threading so that events from the game would update information in the interface, packaging an application for Windows machines... how to handle updates.. how to collaborate with other people and use version control tools like Git. ...it hindsight it really got out of hand! There is so much information on the internet now, so many resources and "experts" that it can actually be really intimidating and difficult to learn something new. Like others have said, everyone has their own style and a way of learning that works best for them. What worked for me is really just coming up with an idea for a project. Start with something simple and try and implement it. Python's official documentation (for the most part) is pretty approachable. When you hit an issue or are unsure how to solve a problem, search the web and see if other people have had similar problems. Find out what they did to solve it. Read their code and try and understand it, at least conceptually. Then when you finish that project, come up with a new one. Add more features to it. If you can come up with a solid idea that you're passionate about, the rest will come. Good luck on your journey! On 14/6/23 07:44, Alan Gauld via Tutor wrote: > On 13/06/2023 19:28, Mats Wichmann wrote: > >> One of the real problems when there are too many offerings is finding >> one that is (a) any good and (b) fits your learning style > ... > >> Be nice if we could do a bit better here on tutor, but I, at least, >> don't see a way (Alan?). > I don't think it's possible. As you say, there are different > learning styles. One person's good tutorial is the next > person's nightmare. > > My own tutorial is aimed at a very specific type of learner; > namely one who wants to learn to program, but is already quite > experienced around computers - more than a casual web browser, > social media jockey etc. It suits those from that user-base > who want a "serious" tutorial. But if they want games, > medals and flags it's not going to work for them. > > Other tutorials target those who just want to learn Python for > a specific purpose, but that could be as trivial as writing > macros for some application(Gimp say, or vim) to doing advanced > science or data analysis at university research level. > > I honestly don't think there is any way to categorize tutorials > for something as general as Python that would be useful to all. > From PythonList at DancesWithMice.info Wed Jun 14 23:17:11 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 15 Jun 2023 15:17:11 +1200 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: References: Message-ID: <6538dafe-30fc-23b3-72fe-758e8b768b0c@DancesWithMice.info> On 14/06/2023 09.44, Alan Gauld via Tutor wrote: > On 13/06/2023 19:28, Mats Wichmann wrote: > >> One of the real problems when there are too many offerings is finding >> one that is (a) any good and (b) fits your learning style > >> Be nice if we could do a bit better here on tutor, but I, at least, >> don't see a way (Alan?). > > I don't think it's possible. As you say, there are different > learning styles. One person's good tutorial is the next > person's nightmare. > > My own tutorial is aimed at a very specific type of learner; > namely one who wants to learn to program, but is already quite > experienced around computers - more than a casual web browser, > social media jockey etc. It suits those from that user-base > who want a "serious" tutorial. But if they want games, > medals and flags it's not going to work for them. > > Other tutorials target those who just want to learn Python for > a specific purpose, but that could be as trivial as writing > macros for some application(Gimp say, or vim) to doing advanced > science or data analysis at university research level. The idea of "Learning Styles" is concerning. It is 'pop-psy', because the idea seems so easy to recognise within one's self*. Evidently there is a basis in truth, therefore the whole thing must be true(?). However, the idea has been de-bunked by serious researchers. * this phenomenon repeated in every psych course, whereby the students each self-diagnose themselves to be suffering from any and every psychosis known to man - or at least the ones covered in that course. (see also medical students learning about sundry diseases) Worse, the idea that I have (only one) learning-style, is a tendency towards 'damage', in the sense that as soon as someone says "it has to happen like this..." (s)he is rejecting all other possibilities, without factual (or critical) basis. Ultimately, if you tell others that there is only one way *you* will do things, they won't want you on their teams, invite you to their parties, etc. There is no question that we have individual biases. Speaking personally, I enjoy using my Kindle for fiction, but prefer paper-books for technical stuff - I'm used to recalling the location of information as 'how far through the book', 'which side of the page', and similar. In like mind, I find videos awkward, even recorded lectures, and even knowing that I've gained the advantage of rewind-and-replay. That said, just as during synchronous lectures, I take notes and rely upon those for 'replay'. (free hint: one of THE most valuable learning tools EVER - providing, providing, providing, you go back and review...) Another piece of (related) spurious pop-psy is the "10,000 hours" quotation. Ericsson (the reputed author) himself, spent years and considerable effort attempting to undo the 'damage' done by reporters (Malcolm Gladwell, and others) who seized upon the number which was only an observation, and turned it into a 'target' - forgetting that there are (many) other factors which affect learning. (you will note that the better critics target Gladwell rather than Ericsson, but ...) For example, someone with low physical coordination, eg can't catch a ball; can improve their skills - but it highly unlikely to ever become an Olympic-level athlete (despite being allowed to drive a car which requires similar relative-motion 'calculations') The point that Ericsson noted, and which @Alan encourages (see Tutorial and other conversations), is that learning does not take place in one 'flash' - by reading a paragraph, watching a video-clip, or hearing an audio-snippet. Learning needs to be consolidated. Learning also needs to be proven. The former leads to ideas such as "spaced repetition". The latter to "deliberative practice" (no, that's not a spelling mistake!). This is where the learner practices what (s)he has learned. In our case: actually writes code to solve some problem - and keeps at it until the script works. Doing this repeatedly is equivalent to the musicians Ericsson observed, practising their art, for hours every day (for years - thus hours * days * years ~ 10,000!). This takes fortitude and inner determination ("intrinsic motivation"). Without that, without YOU maintaining a constant enthusiasm to get yourself to where you want to be, the rest is just static-noise (or even, excuses to prepare yourself for failure). That said, I mentioned working in a team. Accordingly, yes, there is a place for extrinsic (external) factors. Perhaps the best of these for any (every?) trainee (counting Python-Masters in such a mode), is to find a mentor or coach. This person does not need to be a fantastic Python coder, but someone who understands the challenges, can empathise with your situation, and provide encouragement. The commentary on "practice" leads some to recommend what is called 'the Project approach to learning'. Whereas a curriculum-based course attempts to provide a 'complete' coverage of the basics, usually under some sub-heading (pick a heading, eg Python for Data Science); project-based is exactly that. The former tends to evoke comments such as "I'm just ploughing my way through all these lectures" (see earlier comments about the need to stop and consolidate 'learning' with "practise"!) Conversely, the latter maintains interest through challenge: don't know how to do this bit? - well go away and learn then. Powerful (extrinsic) motivation (to problem-solving types)! I was surprised by the number of people joining a recent PythonTraining Co-op, who self-identified as Python-Journeymen, but who had also noticed that great chunks of 'basic knowledge' about Python had been 'missed-out' - accordingly we talked about how to use a more traditional (curriculum-based) course to best fill-in the gaps between their "islands of knowledge". There's no such thing as a "silver bullet"! Seeing you asked (did you ask? OK, just in case) I favor a mixture of them both. Sometimes, show a 'solution' using the tools necessary, then ask the trainee to 'go and do thou likewise' with a similar problem. Sometimes, here's a problem, think about it - oh, is something perplexing you? here's some Python tools which will be helpful, ah now that makes it easy/ier... FYI looking at our Internet courses' dashboards. MOST trainees fail to utilise or fail to finish watching the (expensive-to-produce) video content - apparently preferring the written explanations (despite what the training platforms would have us believe - and trumpet all-day-long). Similarly, university librarians repeatedly report students given a choice of eBook or paper will most likely choose the latter - even the so-called 'digirati' generation(s)! Secondly, the biggest cause of drop-out is loss of motivation (compared to other matters when 'life happens'). Those who do the practical stuff succeed (in career or hobby). Whereas, those who (rush through) and only commit their understanding to short-term memory in order to pass the final-exam (and gain the 'wall-paper'), are no use to anyone when they're sat in front of an IDE and a spec - particular three months later! Cognitive Psychology is my research topic. (but I'd better stop writing here) YMMV! -- Regards, =dn From threesomequarks at proton.me Thu Jun 15 00:36:12 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Thu, 15 Jun 2023 04:36:12 +0000 Subject: [Tutor] I learn pretty much everything visually In-Reply-To: <6538dafe-30fc-23b3-72fe-758e8b768b0c@DancesWithMice.info> References: <6538dafe-30fc-23b3-72fe-758e8b768b0c@DancesWithMice.info> Message-ID: <9qluc7Hte-r1WHIV4_nfskl_CK-QvXLme2NlUs9eq7o26l_UgMGQ_atWNdkINrfZSUViwfNq3BdP6pBb2lq08Gj0cqiCxORcUaXMthsLtQ0=@proton.me> Wow, that is one long reply DN and clearly a topic you think much about. I too have been hesitant about concepts like everyone needing to be taught the one way that works for them. That does not match reality for me as I don't think I have any one dominant modality. I find many useful in combination especially if I want to remember what I learn. My theory is about flexibility. People who use various methods to adjust to whatever is around them can often do better in many areas of life. Yes, some people cannot use all methods. Color-blind people may not easily read some graphs for example, and blind and deaf people obviously may need alternate methods or something like a translation into a medium they can use. The same applies for people who do not speak the language some of the instruction is in fluently or at all. For many people, lectures work and yet others prefer texts and so on. I find many to be complementary as lectures can share things like enthusiasm or what the lecturer thinks is important or cover mostly what will be on the test while the book covers much more widely. But both (and other forms such as one-on-one tutoring or programming assignments) will often not be at the level you are looking for. In my view, general computer understanding is a good thing to have before actually focusing in on one language to use. Do you want to learn about loops within python or enter a course knowing some general things about loops and learning which kids python supports and how they differ from each other or from those in other languages? Just to end with this one example, how many things in languages like python are really loops even if you do not see them? Consider operations like list comprehensions where the loop is still somewhat visible, to generators which yield results on demand but yet are loops internally to vectorized operations such as adding two vectors or multiplying matrices. Consider using objects that look like they are doing things atomically but internally use loops or functions you can call and pass it another function which it invokes repeatedly on members of a list you supply and returns a list of the changed things. You may not see a loop and some forms of learning may make you think you are seeing lots of unrelated features. Or you may learn ane way and be puzzled when others show their code. So, ideally, you learn a bit about general computer ideas and instantiate that knowledge in something like python. But learning from books or videos is probably not enough for those of us without photographic memories. As DN and others say, practice and experience can help drum things in. But skipping the learning part and just copying code and trying it out is also not ideal. A mixture can be more than the sum of the parts. There is nothing wrong with favoring some mode of learning any more than of being lefthanded. But never using one hand does not really make good use of what you have. Sure, people teaching should consider using approaches that people can use but with few exceptions, I think the student is responsible for figuring out how to get SOMETHING from many different styles. But sticking with it can be important if the course you take starts as too basic and if it is too advanced, consider finding what you are missing before resuming. Python has so many resources out there, that something should be useful, albeit not necessarily the free stuff but also not necessarily the expensive stuff. I have rarely found a need to pay especially when enough material is freely online or in Library books I can just borrow. Q Sent with Proton Mail secure email. ------- Original Message ------- On Wednesday, June 14th, 2023 at 11:17 PM, dn via Tutor wrote: > On 14/06/2023 09.44, Alan Gauld via Tutor wrote: > > > On 13/06/2023 19:28, Mats Wichmann wrote: > > > > > One of the real problems when there are too many offerings is finding > > > one that is (a) any good and (b) fits your learning style > > > > > Be nice if we could do a bit better here on tutor, but I, at least, > > > don't see a way (Alan?). > > > > I don't think it's possible. As you say, there are different > > learning styles. One person's good tutorial is the next > > person's nightmare. > > > > My own tutorial is aimed at a very specific type of learner; > > namely one who wants to learn to program, but is already quite > > experienced around computers - more than a casual web browser, > > social media jockey etc. It suits those from that user-base > > who want a "serious" tutorial. But if they want games, > > medals and flags it's not going to work for them. > > > > Other tutorials target those who just want to learn Python for > > a specific purpose, but that could be as trivial as writing > > macros for some application(Gimp say, or vim) to doing advanced > > science or data analysis at university research level. > > > The idea of "Learning Styles" is concerning. It is 'pop-psy', because > the idea seems so easy to recognise within one's self*. Evidently there > is a basis in truth, therefore the whole thing must be true(?). However, > the idea has been de-bunked by serious researchers. > > * this phenomenon repeated in every psych course, whereby the students > each self-diagnose themselves to be suffering from any and every > psychosis known to man - or at least the ones covered in that course. > (see also medical students learning about sundry diseases) > > > Worse, the idea that I have (only one) learning-style, is a tendency > towards 'damage', in the sense that as soon as someone says "it has to > happen like this..." (s)he is rejecting all other possibilities, without > factual (or critical) basis. Ultimately, if you tell others that there > is only one way you will do things, they won't want you on their > teams, invite you to their parties, etc. > > There is no question that we have individual biases. Speaking > personally, I enjoy using my Kindle for fiction, but prefer paper-books > for technical stuff - I'm used to recalling the location of information > as 'how far through the book', 'which side of the page', and similar. In > like mind, I find videos awkward, even recorded lectures, and even > knowing that I've gained the advantage of rewind-and-replay. That said, > just as during synchronous lectures, I take notes and rely upon those > for 'replay'. (free hint: one of THE most valuable learning tools EVER - > providing, providing, providing, you go back and review...) > > > Another piece of (related) spurious pop-psy is the "10,000 hours" > quotation. Ericsson (the reputed author) himself, spent years and > considerable effort attempting to undo the 'damage' done by reporters > (Malcolm Gladwell, and others) who seized upon the number which was only > an observation, and turned it into a 'target' - forgetting that there > are (many) other factors which affect learning. (you will note that the > better critics target Gladwell rather than Ericsson, but ...) For > example, someone with low physical coordination, eg can't catch a ball; > can improve their skills - but it highly unlikely to ever become an > Olympic-level athlete (despite being allowed to drive a car which > requires similar relative-motion 'calculations') > > The point that Ericsson noted, and which @Alan encourages (see Tutorial > and other conversations), is that learning does not take place in one > 'flash' - by reading a paragraph, watching a video-clip, or hearing an > audio-snippet. > > Learning needs to be consolidated. Learning also needs to be proven. The > former leads to ideas such as "spaced repetition". The latter to > "deliberative practice" (no, that's not a spelling mistake!). > > This is where the learner practices what (s)he has learned. In our case: > actually writes code to solve some problem - and keeps at it until the > script works. Doing this repeatedly is equivalent to the musicians > Ericsson observed, practising their art, for hours every day (for years > - thus hours * days * years ~ 10,000!). This takes fortitude and inner > determination ("intrinsic motivation"). Without that, without YOU > maintaining a constant enthusiasm to get yourself to where you want to > be, the rest is just static-noise (or even, excuses to prepare yourself > for failure). > > > That said, I mentioned working in a team. Accordingly, yes, there is a > place for extrinsic (external) factors. Perhaps the best of these for > any (every?) trainee (counting Python-Masters in such a mode), is to > find a mentor or coach. This person does not need to be a fantastic > Python coder, but someone who understands the challenges, can empathise > with your situation, and provide encouragement. > > > The commentary on "practice" leads some to recommend what is called 'the > Project approach to learning'. Whereas a curriculum-based course > attempts to provide a 'complete' coverage of the basics, usually under > some sub-heading (pick a heading, eg Python for Data Science); > project-based is exactly that. The former tends to evoke comments such > as "I'm just ploughing my way through all these lectures" (see earlier > comments about the need to stop and consolidate 'learning' with > "practise"!) Conversely, the latter maintains interest through > challenge: don't know how to do this bit? - well go away and learn then. > Powerful (extrinsic) motivation (to problem-solving types)! > > I was surprised by the number of people joining a recent PythonTraining > Co-op, who self-identified as Python-Journeymen, but who had also > noticed that great chunks of 'basic knowledge' about Python had been > 'missed-out' - accordingly we talked about how to use a more traditional > (curriculum-based) course to best fill-in the gaps between their > "islands of knowledge". There's no such thing as a "silver bullet"! > > Seeing you asked (did you ask? OK, just in case) I favor a mixture of > them both. Sometimes, show a 'solution' using the tools necessary, then > ask the trainee to 'go and do thou likewise' with a similar problem. > Sometimes, here's a problem, think about it - oh, is something > perplexing you? here's some Python tools which will be helpful, ah now > that makes it easy/ier... > > > > FYI looking at our Internet courses' dashboards. MOST trainees fail to > utilise or fail to finish watching the (expensive-to-produce) video > content - apparently preferring the written explanations (despite what > the training platforms would have us believe - and trumpet > all-day-long). Similarly, university librarians repeatedly report > students given a choice of eBook or paper will most likely choose the > latter - even the so-called 'digirati' generation(s)! Secondly, the > biggest cause of drop-out is loss of motivation (compared to other > matters when 'life happens'). > > Those who do the practical stuff succeed (in career or hobby). Whereas, > those who (rush through) and only commit their understanding to > short-term memory in order to pass the final-exam (and gain the > 'wall-paper'), are no use to anyone when they're sat in front of an IDE > and a spec - particular three months later! > > > Cognitive Psychology is my research topic. > (but I'd better stop writing here) > > YMMV! > > -- > Regards, > =dn > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From katherinegillig7 at gmail.com Sun Jun 18 12:22:54 2023 From: katherinegillig7 at gmail.com (Katherine Gillig) Date: Sun, 18 Jun 2023 12:22:54 -0400 Subject: [Tutor] Question Message-ID: Hello, I'm following a YouTube tutorial to learn Python. I'm very early in, and I'm trying to input a series of underscores/hyphens such that the command window will spit out a shape that looks like a triangle. However, when I run it, "Hi PyCharm" pops out instead of the triangle. I have PyCharm installed, which is where that's coming from. Could you help with this? From alan.gauld at yahoo.co.uk Sun Jun 18 15:23:53 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 18 Jun 2023 20:23:53 +0100 Subject: [Tutor] Question In-Reply-To: References: Message-ID: On 18/06/2023 17:22, Katherine Gillig wrote: > Hello, > > I'm following a YouTube tutorial to learn Python. I'm very early in, and > I'm trying to input a series of underscores/hyphens such that the command > window will spit out a shape that looks like a triangle. However, when I > run it, "Hi PyCharm" pops out instead of the triangle. I have PyCharm > installed, which is where that's coming from. Could you help with this? Hi, the list server will not allow binary attachments for security reasons. Please repost with the text from the screen copy/pasted into the message. (Also use plain text mode to keep the text formatting which is critical in Python) Additional information that will help us figure out what's happening includes: 1) OS type and version 2) Python version 3) How you ran your program(inside an IDE, which one? Or from a command line? Show us the actual command typed) 4) A link to your youTube tutorial. 5) Your code(pasted as per above) 6) Any error messages(in full please) That looks a lot but the more you tell us the easier it is to give an accurate answer. -- 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 kolbe.business at gmail.com Mon Jun 19 09:40:00 2023 From: kolbe.business at gmail.com (Arthur Kolbe) Date: Mon, 19 Jun 2023 15:40:00 +0200 Subject: [Tutor] Question about python code that is not working Message-ID: I want to be able to put a list of websites into this program and the program to crawl all pages of the websites I entered, to then check for any 404 pages. Then I want the program to create a csv file with two columns, in the left column all websites I entered, and in the right column, the status of the websites, with either "no 404 pages found on this website" or "404 pages found on this website". Or "website not found" if the website can't be reached. This is the code I tried to build but it's not working. If you could tell me what I'm doing wrong and how to fix, that would be amazing! Thanks in advance! Code: *import* csv *import* scrapy *from* scrapy.crawler *import* CrawlerRunner *from* scrapy.spiders *import* CrawlSpider, Rule *from* scrapy.linkextractors *import* LinkExtractor *from* scrapy.utils.project *import* get_project_settings *from* twisted.internet *import* reactor *class* PageChecker(CrawlSpider): name = 'page_checker' custom_settings = { 'DOWNLOAD_DELAY': 1, 'CONCURRENT_REQUESTS': 4, 'USER_AGENT': 'Mozilla/5.0 (compatible; Googlebot/2.1; + http://www.google.com/bot.html)', 'LOG_LEVEL': 'ERROR' } *def* __init__(self, websites=*None*, **kwargs): self.start_urls = websites self.allowed_domains = [self.extract_domain(url) *for* url *in* websites] self.rules = [Rule(LinkExtractor(allow=()), callback=self.parse_page, follow=*True*)] self.results = {} # Track results for each URL super().__init__(**kwargs) @staticmethod *def* extract_domain(url): *return* url.split('//')[-1].split('/')[0] *def* parse_page(self, response): status_code = response.status *if* status_code == 404: self.results.setdefault(response.url, *True*) *def* closed(self, reason): save_to_csv(self.results) *def* check_404_pages(websites): results = {} runner = CrawlerRunner(get_project_settings()) *for* website *in* websites: runner.crawl(PageChecker, websites=[website], results=results) # Pass the spider class and results dictionary d = runner.join() d.addBoth(*lambda* _: save_to_csv(results)) # Save results to CSV after the crawl is complete *def* save_to_csv(results): csv_file_path = '404_results.csv' *with* open(csv_file_path, 'w', newline='') *as* csvfile: writer = csv.writer(csvfile) writer.writerow(['URL', 'Status']) *for* url, _ *in* results.items(): writer.writerow([url, '404 Pages Found']) *if* *not* results: print("No 404 pages found.") *else*: print("CSV file created successfully.") websites = [ "https://osteopathie.org", "https://hpo-osteopathie.de", "https://osteopathiezentrum.de" ] # Check for 404 pages by crawling all pages of the websites and save the results to a CSV file check_404_pages(websites) reactor.run() Kind regards, Arthur From PythonList at DancesWithMice.info Mon Jun 19 14:55:18 2023 From: PythonList at DancesWithMice.info (dn) Date: Tue, 20 Jun 2023 06:55:18 +1200 Subject: [Tutor] Question about python code that is not working In-Reply-To: References: Message-ID: <62d103b1-64d9-9e12-a350-50eab8ce47cf@DancesWithMice.info> Arthur, We'd like to help. Two things will help us to help you: - please copy-paste the code as simple-text. With all the formatting we can't copy-paste into our systems to see what happens - tell us 'what happens'. The words "not working...doing wrong" don't even hint where the problem lies. What error messages result? (again, please copy-paste the details - and if necessary translate pertinent line-numbers (because there will be none in the copy-pasted code!) Focus: Can the code be minimised? For example, if the problem is to do with the .CSV file, what happens if the code is shortened, and sample data is 'injected' straight into that function? On 20/06/2023 01.40, Arthur Kolbe wrote: > I want to be able to put a list of websites into this program and the > program to crawl all pages of the websites I entered, to then check for any > 404 pages. Then I want the program to create a csv file with two columns, > in the left column all websites I entered, and in the right column, the > status of the websites, with either "no 404 pages found on this website" or > "404 pages found on this website". Or "website not found" if the website > can't be reached. This is the code I tried to build but it's not working. > If you could tell me what I'm doing wrong and how to fix, that would be > amazing! Thanks in advance! > > Code: > > *import* csv > > *import* scrapy > > *from* scrapy.crawler *import* CrawlerRunner > > *from* scrapy.spiders *import* CrawlSpider, Rule > > *from* scrapy.linkextractors *import* LinkExtractor > > *from* scrapy.utils.project *import* get_project_settings > > *from* twisted.internet *import* reactor > > > > *class* PageChecker(CrawlSpider): > > name = 'page_checker' > > custom_settings = { > > 'DOWNLOAD_DELAY': 1, > > 'CONCURRENT_REQUESTS': 4, > > 'USER_AGENT': 'Mozilla/5.0 (compatible; Googlebot/2.1; + > http://www.google.com/bot.html)', > > 'LOG_LEVEL': 'ERROR' > > } > > > *def* __init__(self, websites=*None*, **kwargs): > > self.start_urls = websites > > self.allowed_domains = [self.extract_domain(url) *for* url *in* > websites] > > self.rules = [Rule(LinkExtractor(allow=()), > callback=self.parse_page, follow=*True*)] > > self.results = {} # Track results for each URL > > super().__init__(**kwargs) > > > @staticmethod > > *def* extract_domain(url): > > *return* url.split('//')[-1].split('/')[0] > > > *def* parse_page(self, response): > > status_code = response.status > > *if* status_code == 404: > > self.results.setdefault(response.url, *True*) > > > *def* closed(self, reason): > > save_to_csv(self.results) > > > > *def* check_404_pages(websites): > > results = {} > > > runner = CrawlerRunner(get_project_settings()) > > > *for* website *in* websites: > > runner.crawl(PageChecker, websites=[website], results=results) # > Pass the spider class and results dictionary > > > d = runner.join() > > d.addBoth(*lambda* _: save_to_csv(results)) # Save results to CSV > after the crawl is complete > > > > *def* save_to_csv(results): > > csv_file_path = '404_results.csv' > > > *with* open(csv_file_path, 'w', newline='') *as* csvfile: > > writer = csv.writer(csvfile) > > writer.writerow(['URL', 'Status']) > > *for* url, _ *in* results.items(): > > writer.writerow([url, '404 Pages Found']) > > > *if* *not* results: > > print("No 404 pages found.") > > *else*: > > print("CSV file created successfully.") > > > > websites = [ > > "https://osteopathie.org", > > "https://hpo-osteopathie.de", > > "https://osteopathiezentrum.de" > > > > ] > > > # Check for 404 pages by crawling all pages of the websites and save the > results to a CSV file > > check_404_pages(websites) > > reactor.run() > > > > Kind regards, > > Arthur > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Regards, =dn From PythonList at DancesWithMice.info Mon Jun 19 18:39:14 2023 From: PythonList at DancesWithMice.info (dn) Date: Tue, 20 Jun 2023 10:39:14 +1200 Subject: [Tutor] Question about python code that is not working In-Reply-To: References: <62d103b1-64d9-9e12-a350-50eab8ce47cf@DancesWithMice.info> Message-ID: <6ca07f1f-58aa-d62e-b8a2-0e16f5354f5f@DancesWithMice.info> Apologies if it feels as if I keep telling you what to do: please answer to the list so that (a) others can jump-in and assist you, and (b) if anyone else is suffering a similar problem, they can gain (almost) as much as you - also a reason for selecting a meaningful subject-line for email messages! Now, let's talk:- On 20/06/2023 09.56, Arthur Kolbe wrote: > Hey again! I've been working on my code for some more, many things that > needed to be improved. This is the code as of right now: ... > > What I want is this: > > Software > > Enter websites The way you have broken-down the problem into smaller sub-problems (and they into smaller ...) is good analysis and design! When ready to code, what I do is take that narrative specification and turn it into Python function-names and docstrings. This is workable if the sub-problems have been broken-down sufficiently - and works on the grounds that each sub-problem will require one (or more) functions in which to code its solution. In this fashion, the top-down design becomes a bottom-up construction. As the sub-problems are solved, the slightly-larger sub-problems can be addressed - often a matter of ensuring that the sub-problem solutions "integrate" correctly (hence term: "integration testing"). Continuing until it's 'all done'. Ah, would that life were so easy... Thus, starting from those function-names and docstring solution-methods, I code those sub-problem solutions, one at a time. This means that I can also* build a (set of) test(s) to ensure that I've got that (little) bit correct - it's so much easier to see where things have gone-wrong if there is only one function in-play! * I (try to - but am human/lazy/often trying to work quickly) use a technique called "TDD" (Test-Driven Development) which suggests that one should use the spec to write the test *first*, and then write code which will *deliver* to spec. [however such is possibly a distraction at this moment. So, tuck it behind you ear, and come back to it when you're inclined] Thus, if this sub-problem: "enter websites", is built as a self-contained function, can the function be given a URL as argument, and respond with the page-header and/or content? There we go - first test written, and (making assumption) first sub-problem solved! Get the idea? (see also "Modular Programming") > Software checks website if crawling forbidden or not Good practice! > If allowed, crawls every page on website, looks for 404/410 pages that > were once present on the website (status code 200) There are Linux tools which do this (curl and wget). They have options to create/vary a pause between making requests of a site - to avoid 'hammering' the server. May be worth a perusal... > Creates CSV. > > ?Two tables. Both two columns. Table 1 Left C: All websites one > entered, Right C: EITHER "404 pages found on website", "no 404 pages > found on website", "Scraping not allowed" or "Website can't be reached". > Remember, the entire websites are supposed to be crawled for 404 pages. > So in the second table in the left column all pages that were found. > right column status code. This second table in the csv is so that I can > Make sure the program did or didnt find 404 pages. Business folk can't seem to get enough of spreadsheets (although this is a .CSV file, cf using openpyxl (or some-such) to build a spreadsheet directly). Whereas a web-site verifier/monitor like this, and Python program[me]s which run 'in the background', are often better-off tracking progress and results in a "log". There is even a logging library in the PSL (Python Standard Library)! > and what is happening right now is this: > the code when running, creates one file with all pages it finds to the > first website I enter, then when done with crawling that website, > creates another file with the same name in the same directory, Oops! This problem wouldn't happen if a single log-file were being employed - similarly a single workbook (although would still find same issue if delivered as a separate work-sheet for each web-site). The "websites" list of URLs to be inspected needs to be accompanied by a 'destination' file-name (for this purpose). Alternately, if you can guarantee unique naming, perhaps use urllib.parse to split each URL into components and use the web-site (netloc) - with or without TLD; as the file-name? > overwriting the old one, where all the pages of the second website I > entered are, then the third, and when its done it creates one last file > where all the websites that were entered are shown in a table in the > left column but for some reason it says "website cant be reached" for > them in the right column although like I just said all the pages of the > websites were found in the files created before. First two files are > just the second table so to say but only for one website, the last file > is only the first table so to say but not correct. Re-read this and note how it is difficult to locate exactly where the error starts - because it is only revealed at the reporting stage. > Thanks for helping in advance! The 'help' is non-specific. Should you decide to change the delivery method or implement the naming-scheme, maybe the problem is solved. However, better practise will help. If smaller units are tested in-isolation, the problem will (likely) be revealed sooner, ie calling a function and *not* gaining the result desired (tested for). If you are able to narrow-down the code the way you have narrowed-down the problem-description, I think you will have it beaten (and the next bug, and those in the next program[me]... -- Regards, =dn From harshmohan009 at gmail.com Tue Jun 20 02:53:43 2023 From: harshmohan009 at gmail.com (HARSH MOHAN) Date: Tue, 20 Jun 2023 12:23:43 +0530 Subject: [Tutor] Tutor Digest, Vol 232, Issue 12 In-Reply-To: References: Message-ID: firstly if you are a new learner try python script mode from python.org website because pycharm is for building high level projects and for your code use three inverted codes as:* print( """ write your thing here """)* for example I have attached photo and source code. On Mon, 19 Jun 2023 at 21:32, 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. Question (Katherine Gillig) > 2. Re: Question (Alan Gauld) > > > > ---------- Forwarded message ---------- > From: Katherine Gillig > To: tutor at python.org > Cc: > Bcc: > Date: Sun, 18 Jun 2023 12:22:54 -0400 > Subject: [Tutor] Question > Hello, > > I'm following a YouTube tutorial to learn Python. I'm very early in, and > I'm trying to input a series of underscores/hyphens such that the command > window will spit out a shape that looks like a triangle. However, when I > run it, "Hi PyCharm" pops out instead of the triangle. I have PyCharm > installed, which is where that's coming from. Could you help with this? > > > > > ---------- Forwarded message ---------- > From: Alan Gauld > To: tutor at python.org > Cc: > Bcc: > Date: Sun, 18 Jun 2023 20:23:53 +0100 > Subject: Re: [Tutor] Question > On 18/06/2023 17:22, Katherine Gillig wrote: > > Hello, > > > > I'm following a YouTube tutorial to learn Python. I'm very early in, and > > I'm trying to input a series of underscores/hyphens such that the command > > window will spit out a shape that looks like a triangle. However, when I > > run it, "Hi PyCharm" pops out instead of the triangle. I have PyCharm > > installed, which is where that's coming from. Could you help with this? > > Hi, the list server will not allow binary attachments for security reasons. > > Please repost with the text from the screen copy/pasted into the > message. (Also use plain text mode to keep the text formatting which > is critical in Python) > > Additional information that will help us figure out what's happening > includes: > 1) OS type and version > 2) Python version > 3) How you ran your program(inside an IDE, which one? > Or from a command line? Show us the actual command typed) > 4) A link to your youTube tutorial. > 5) Your code(pasted as per above) > 6) Any error messages(in full please) > > > That looks a lot but the more you tell us the easier it is to > give an accurate answer. > > -- > 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 > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Tue Jun 20 08:19:03 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 20 Jun 2023 13:19:03 +0100 Subject: [Tutor] Tutor Digest, Vol 232, Issue 12 In-Reply-To: References: Message-ID: On 20/06/2023 07:53, HARSH MOHAN wrote: Thanks for your contribution but please do not repost the entire digest(even if only 2 messages, as here). We have all seen them already and some people pay by the byte for internet access. Also changing the subject line will help folks find it in the future. > firstly if you are a new learner try python script mode from python.org > website because pycharm is for building high level projects > and for your code use three inverted codes as:* print( """ write your thing > here """)* Triple quotes don't normally offer any advantage for short strings and can lead to obscure bugs. Is there some extra advantage if using PyCharm? > for example I have attached photo and source code. The photo will be stripped by the server as a security risk. The source would get through if its plain text. -- 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 PythonList at DancesWithMice.info Tue Jun 20 18:47:33 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 21 Jun 2023 10:47:33 +1200 Subject: [Tutor] PyCharm and triple quotes - Was: Tutor Digest, Vol 232, Issue 12 In-Reply-To: References: Message-ID: <3da1df85-e110-8c8f-1041-eed458537356@DancesWithMice.info> On 21/06/2023 00.19, Alan Gauld via Tutor wrote: > On 20/06/2023 07:53, HARSH MOHAN wrote: ... >> website because pycharm is for building high level projects Yes, use the Python-REPL, working line-by-line, for experimenting, testing your own knowledge, and similar. Yes, could use a light-weight text-editor, eg xed, nano, notepad; to dash-off a short code-snippet (and run from command-line) - rather than waiting for a full-fat IDE to load. However, both of those are available within PyCharm, if it is already running. Don't most Python.devs have their IDE running all-the-time? >> and for your code use three inverted codes as:* print( """ write your thing >> here """)* > > Triple quotes don't normally offer any advantage for short strings > and can lead to obscure bugs. Is there some extra advantage if > using PyCharm? None! Like most 'intelligent' editors, as soon as one opens a string*, PyCharm will auto-magically enter the closing-delimiter. Anything typed will become part of the string... * apostrophe/single-quotation mark, double quotes/quotation mark, or either of the triple-quotes Personally, reserve triple-quotes for docstrings (my PyCharm flags any function (etc) def-ined without a docstring!), unless have some long, multi-line string to be reproduced verbatim. Quotation-marks are used for strings, on the grounds that am more likely to encounter a possessive (and thus apostrophe + s) within some narrative, than to need double-quotes) - at which point can either swap* delimiters or use an (ugly) escape. * PyCharm does help with those operations: - if highlight a string and then enter string-delimiter of some kind, it will surround the text and turn it into a string-literal - similarly, if highlight an existing string (including both quotation-marks) and type an alternate string-delimiter, PyCharm will make an intelligent change. Disclaimer: JetBrains sponsor our PUG by donating a monthly door-prize of a 12-month Professional license. I am currently using PyCharm - however, switch between IDEs when working for a period of time, with a team standardised on some other tool... YMMV! -- Regards, =dn From trent.shipley at gmail.com Tue Jun 20 13:13:33 2023 From: trent.shipley at gmail.com (trent shipley) Date: Tue, 20 Jun 2023 10:13:33 -0700 Subject: [Tutor] Like the world needed another dice roller Message-ID: I just did a thing. And I could really use some feedback. If it is lite the feedback I'd get from my last coding job it will go something like: your code works, but I don't understand it, there isn't enough documentation, and what documentation there is, doesn't help. https://github.com/trent-shipley/hackable_dice_roller From phyoung at comcast.net Wed Jun 21 12:25:37 2023 From: phyoung at comcast.net (Peter H Young) Date: Wed, 21 Jun 2023 12:25:37 -0400 Subject: [Tutor] Installing and Running Python Screen Shots Message-ID: <30d061cc-bf93-fa29-5dd3-378f5a4a0d48@comcast.net> Here, the instructions are confusing:? I can take screen shots, but not save them to files?? How then do I select them to upload, in order to complete the lesson.? Doesn't make sense to me. --Pete Young phyoung at comcast.net From wlfraed at ix.netcom.com Wed Jun 21 19:44:00 2023 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Wed, 21 Jun 2023 19:44:00 -0400 Subject: [Tutor] Installing and Running Python Screen Shots References: <30d061cc-bf93-fa29-5dd3-378f5a4a0d48@comcast.net> Message-ID: On Wed, 21 Jun 2023 12:25:37 -0400, Peter H Young declaimed the following: >Here, the instructions are confusing:? I can take screen shots, but not >save them to files?? How then do I select them to upload, in order to >complete the lesson.? Doesn't make sense to me. Your complaint is also confusing. What is "here"? Some web site? Provide a URL. How are you taking these screen shots (and what prevents you from saving them to a file)? And again, what is the URL of that "lesson"? Without such information we have no idea what you are talking about. If this is Windows OS, puts an image into the system clipboard. To create a file, you'll need to open some application that supports graphics editing (Photoship, GIMP, et al), create a new blank image (Photoshop can automatically provide dimensions compatible with the clipboard image), paste the clipboard into this new image, and then save as a file. Otherwise, do any of the items https://www.google.com/search?q=python+screen+shots provide any help From simpsonrmz41 at gmail.com Thu Jun 22 17:45:23 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Fri, 23 Jun 2023 07:45:23 +1000 Subject: [Tutor] Beginner struggling with python. Message-ID: Hello, Please pardon my ignorance but is this email chain for fresh beginners also? I am enrolled in a crash course in python and was following along nicely until we got on to return values and defining functions. Are particular functions built into python such as def convert( etc.? my main issue is syntax required as I feel the course I am in brushed over it quite quickly. Are there any recommendations where I can access more tutorials for beginners to learn more and get good at the basics? Apology?s if I haven?t formatted my email correctly, I am very new to this but I love it and am very eager to learn more. Thanks. From alan.gauld at yahoo.co.uk Thu Jun 22 20:07:10 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 23 Jun 2023 01:07:10 +0100 Subject: [Tutor] Beginner struggling with python. In-Reply-To: References: Message-ID: On 22/06/2023 22:45, Jack Simpson wrote: > Please pardon my ignorance but is this email chain for fresh beginners > also? Absolutely. Beginners to programming and beginners to Python (regardless of programming experience). > nicely until we got on to return values and defining functions. Are > particular functions built into python such as def convert( etc. There are function built into Python (and these are called builtins!:) There's a lot more functions that come with Python in the form of modules. You can add your own functions to your program or You can create your own modules and share these across programs or even with your friends and colleagues. Defining functions is how we extend the basic language to do more powerful things so that we can solve bigger problems. > my main issue is syntax required as I feel the course I am in brushed over > it quite quickly. Here is an excerpt from my tutorials chapter on functions (there's a lot more on the web page, see the link in my .sig): ================== The basic structure of a function call is as follows: aValue = someFunction ( anArgument, another, etc... ) That is, the variable aValue takes on the value obtained by calling a function called someFunction. The function can accept, inside parentheses, zero or many arguments which it treats like internal variables. Functions can call other functions internally. In most programming languages, even if there are no arguments, we must still provide the parentheses when calling a function. (Although VBScript is an example of a language which does not require parentheses, even when there are arguments, but it usually makes things clearer to include them.) ... Defining our own functions -------------------------- OK, so we know how to use the existing functions and modules, but how do we create a new function? Simply by defining it. That is we write a statement which tells the interpreter that we are defining a block of code that it should execute, on demand, elsewhere in our program. VBScript first -------------- So let's create a function that can print out a multiplication table for us for any value that we provide as an argument. In VBScript it looks like: We start with the keyword Sub (for Subroutine) and end the definition with End Sub, following the normal VBScript block marker style. We provide a list of parameters enclosed in parentheses. The code inside the defined block is just normal VBScript code with the exception that it treats the parameters as if they were local variables. So in the example above the function is called Times and it takes a single parameter called N. It also defines a local variable I. It then executes a loop to display the N times table, using both N and I as variables. ... In Python the Times function looks like: def times(n): for i in range(1,13): print( "%d x %d = %d" % (i, n, i*n) ) And is called like: print( "Here is the 9 times table..." ) times(9) Note that in Python procedures are not distinguished from functions and the same name def is used to define both. The only difference is that a function which returns a value uses a return statement, like this: def timesTable(n): s = "" for i in range(1,13): s = s + "%d x %d = %d\n" % (i,n,n*i) return s As you see it's very simply done, just return the result using a return statement. (If you don't have an explicit return statement Python automatically returns a default value called None which we usually just ignore.) We can then print the result of the function like so: print( timesTable(7) ) Although we haven't followed this advice throughout the tutorial, it is usually best to avoid putting print statements inside functions. Instead, get them to return the result and print that from outside the function. That makes your functions much more reusable, in a wider variety of situations. There is one very important thing to remember about return. Not only does it return a value from the function but it also immediately returns control back to the code that called the function. This is important because the return does not have to be the last line in the function, there could be more - and it may never get executed. Indeed there can be more than one return statement in a function body and whichever return is reached first will terminate the function and return its value to the calling code. ================= I hope that helps! :-) > Are there any recommendations where I can access more tutorials for > beginners to learn more and get good at the basics? > There is a web page with a long list on python.org: https://wiki.python.org/moin/BeginnersGuide/NonProgrammers It includes mine along with many others. Pick one that you find suits your learning style. -- 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 PythonList at DancesWithMice.info Thu Jun 22 22:48:39 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 23 Jun 2023 14:48:39 +1200 Subject: [Tutor] Beginner struggling with python. In-Reply-To: References: Message-ID: <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info> On 23/06/2023 12.07, Alan Gauld via Tutor wrote: > On 22/06/2023 22:45, Jack Simpson wrote: ... >> nicely until we got on to return values and defining functions. Are >> particular functions built into python such as def convert( etc. Yes, Python offers various built-in functions as well as the opportunity to write your own "custom functions". The 'built-ins' include len( string ) which will return the number of characters in the string - or number of elements in a "collection" when used with a list or similar. There are also 'functions' which are part of a data-type (class). Sticking with strings for the moment: string.upper() will ensure each character in that string is converted (where necessary) into upper-case/capital-letters. In Python, we use the term "everything is an object". So, this function is actually a "method" of the str[ing] type/class. There is an important difference between a function and a method - a method works on the value to which is is attached, eg "string" in this case, whereas a function works independently of any specific instance. (see "arguments" and "result" below - but this distinction is a bit curly for a beginner) You can tell which you're dealing-with, by the 'dotted-notation'. Then there are the functions you can write yourself, as @Alan has described. Noting that functions 'take in' certain (optional) values and return a result, the general form is: def name( arguments ): # computation return result The "name" should be a meaningful description of the "computation", ie the purpose of the function. The "arguments" (zero or more) will be a comma-separated list of identifiers which are inputs to the function. In @Alan's example, 7, to produce the seven times-table or 9 when your math is better than mine... The "computation" can be anything which Python will do for you. Sometimes we use a function to attend to a sub-problem within the wider application, ie produces a neatly labelled-result. Another use for functions is when we repeat the same "computation" repeatedly, and perhaps from different points in the application. The "result" seems self explanatory. Every function returns a "result". If there is a return-statement, that will compute a value. If not, the return-value is None. The wording in the singular-form is slightly mis-leading. If appropriate, a function can return a collection of values, eg a tuple or a list - however it is still only one "collection"! We don't have to def-ine built-in functions (or those which are import-ed from a library). The "name( arguments )" and "return result" components are often called the "signature" of the function. Basically, the function says: if you give me this, I'll give you that by-return. Hah! The "signature" is an interface which sets-out all the 'rules' for what you can do with the function - remember the len() example (above), its signature allows us to apply it to a string or a list (or other "collection"). Flexibility! ("polymorphism"). The "signature" also advises what to expect as a result: OK the 'length' part is right there in the function-name, but the signature tells us that the return-value will be an integer. Again, not much of a surprise given that we are expecting a number, and it is hard to have a string with a negative-number of characters or indeed part of a character. However, some functions are less obvious and thus the signature is the means of ensuring that we use the function for the purpose and in the manner its author intended. In the Python REPL try: help( function_name ) Web.Ref: https://docs.python.org/3/library/functions.html#len Using a function is termed "calling a function". As above, this can look like: number_of_characters = len( string ) or seventh_times_table = times_table( 7 ) The general form here is: identifier = function_name( parameters ) The "signature" is also generalised, but is at-least specific to that particular function. Do we need to document that "function_name" has to correspond to a def-statement (either one of our own, or one built-in and provided to us)? The optional parameters must be provided if the function/signature demands. Some may be required. Others may be optional. There is a variety of ways these may be expressed (a story for another day). The function's return-value is passed 'across' the assignment to "number_of_characters" or "seventh_times_table" (or passed directly into the print() function*). The identifier will become the same data-type as the result-data. * you will have noticed that @Alan uses the function's result within a print-call rather than an assignment statement, but we are still making use of the return-value. (just because this very afternoon, I've been helping someone-else who's using it) A free-to-download or read-on-the-web book is Al Sweigart's "Automate the Boring Stuff". Chapter 3 deals with functions (http://automatetheboringstuff.com/2e/chapter3/) It's getting a bit old now, but the basics haven't changed... @Alan mentioned online tutorials, quite possibly anticipating that I'd chime-in with (an alternate/additional view): the suggestion of online courses, eg Coursera, edX, FutureLearn, ... The advantage of these is that they usually present their material in both text and video forms, plus they collect a community of fellow-trainees, who will help each-other with questions and readily-recognise which session/chapter you're working at, right now. (however, re-iterating @Alan's welcome, this Discussion List is also for exactly those kinds of discussions) Disclaimer: I use the edX platform - but not for Python training. -- Regards, =dn From simpsonrmz41 at gmail.com Fri Jun 23 03:22:29 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Fri, 23 Jun 2023 17:22:29 +1000 Subject: [Tutor] Fwd: Beginner struggling with python. In-Reply-To: References: <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info> Message-ID: ---------- Forwarded message --------- From: Jack Simpson Date: Fri, 23 Jun 2023 at 1:58 pm Subject: Re: [Tutor] Beginner struggling with python. To: dn I tried to use the string.upper() and it returned this syntax error. I also tried def upper() and upper(). I also tried underscores and spaces within the string in the parenthesis which produced a similar result but the issue was with the code within the string. I am on a work computer using an interpreter so please forgive the photos from my phone. On Fri, 23 Jun 2023 at 12:51 pm, dn via Tutor wrote: > On 23/06/2023 12.07, Alan Gauld via Tutor wrote: > > On 22/06/2023 22:45, Jack Simpson wrote: > ... > > >> nicely until we got on to return values and defining functions. Are > >> particular functions built into python such as def convert( etc. > > Yes, Python offers various built-in functions as well as the opportunity > to write your own "custom functions". > > The 'built-ins' include len( string ) which will return the number of > characters in the string - or number of elements in a "collection" when > used with a list or similar. > > There are also 'functions' which are part of a data-type (class). > Sticking with strings for the moment: string.upper() will ensure each > character in that string is converted (where necessary) into > upper-case/capital-letters. In Python, we use the term "everything is an > object". So, this function is actually a "method" of the str[ing] > type/class. There is an important difference between a function and a > method - a method works on the value to which is is attached, eg > "string" in this case, whereas a function works independently of any > specific instance. (see "arguments" and "result" below - but this > distinction is a bit curly for a beginner) You can tell which you're > dealing-with, by the 'dotted-notation'. > > Then there are the functions you can write yourself, as @Alan has > described. > > > Noting that functions 'take in' certain (optional) values and return a > result, the general form is: > > def name( arguments ): > # computation > return result > > The "name" should be a meaningful description of the "computation", ie > the purpose of the function. > > The "arguments" (zero or more) will be a comma-separated list of > identifiers which are inputs to the function. In @Alan's example, 7, to > produce the seven times-table or 9 when your math is better than mine... > > The "computation" can be anything which Python will do for you. > Sometimes we use a function to attend to a sub-problem within the wider > application, ie produces a neatly labelled-result. Another use for > functions is when we repeat the same "computation" repeatedly, and > perhaps from different points in the application. > > The "result" seems self explanatory. Every function returns a "result". > If there is a return-statement, that will compute a value. If not, the > return-value is None. The wording in the singular-form is slightly > mis-leading. If appropriate, a function can return a collection of > values, eg a tuple or a list - however it is still only one "collection"! > > > We don't have to def-ine built-in functions (or those which are > import-ed from a library). > > > The "name( arguments )" and "return result" components are often called > the "signature" of the function. Basically, the function says: if you > give me this, I'll give you that by-return. Hah! The "signature" is an > interface which sets-out all the 'rules' for what you can do with the > function - remember the len() example (above), its signature allows us > to apply it to a string or a list (or other "collection"). Flexibility! > ("polymorphism"). > > The "signature" also advises what to expect as a result: OK the 'length' > part is right there in the function-name, but the signature tells us > that the return-value will be an integer. Again, not much of a surprise > given that we are expecting a number, and it is hard to have a string > with a negative-number of characters or indeed part of a character. > However, some functions are less obvious and thus the signature is the > means of ensuring that we use the function for the purpose and in the > manner its author intended. > > In the Python REPL try: help( function_name ) > Web.Ref: https://docs.python.org/3/library/functions.html#len > > > Using a function is termed "calling a function". As above, this can look > like: > > number_of_characters = len( string ) > or > seventh_times_table = times_table( 7 ) > > The general form here is: > > identifier = function_name( parameters ) > > The "signature" is also generalised, but is at-least specific to that > particular function. > > Do we need to document that "function_name" has to correspond to a > def-statement (either one of our own, or one built-in and provided to us)? > > The optional parameters must be provided if the function/signature > demands. Some may be required. Others may be optional. There is a > variety of ways these may be expressed (a story for another day). > > The function's return-value is passed 'across' the assignment to > "number_of_characters" or "seventh_times_table" (or passed directly into > the print() function*). The identifier will become the same data-type as > the result-data. > > * you will have noticed that @Alan uses the function's result within a > print-call rather than an assignment statement, but we are still making > use of the return-value. > > > > (just because this very afternoon, I've been helping someone-else who's > using it) > A free-to-download or read-on-the-web book is Al Sweigart's "Automate > the Boring Stuff". Chapter 3 deals with functions > (http://automatetheboringstuff.com/2e/chapter3/) > It's getting a bit old now, but the basics haven't changed... > > > @Alan mentioned online tutorials, quite possibly anticipating that I'd > chime-in with (an alternate/additional view): the suggestion of online > courses, eg Coursera, edX, FutureLearn, ... The advantage of these is > that they usually present their material in both text and video forms, > plus they collect a community of fellow-trainees, who will help > each-other with questions and readily-recognise which session/chapter > you're working at, right now. > > (however, re-iterating @Alan's welcome, this Discussion List is also for > exactly those kinds of discussions) > > > Disclaimer: I use the edX platform - but not for Python training. > -- > Regards, > =dn > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From leamhall at gmail.com Fri Jun 23 07:16:32 2023 From: leamhall at gmail.com (Leam Hall) Date: Fri, 23 Jun 2023 06:16:32 -0500 Subject: [Tutor] Fwd: Beginner struggling with python. In-Reply-To: References: <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info> Message-ID: <2f61d53c-77ce-e4aa-c1b0-3238af3923d7@gmail.com> Hey Jack, the email list strops off images, attachments, etc. Here's an example, using the python interpreter itself: # Calling the interpreter on a Linux box. [leam at shaphan ~]$ python Python 3.11.3 (main, May 24 2023, 00:00:00) [GCC 12.3.1 20230508 (Red Hat 12.3.1-1)] on linux Type "help", "copyright", "credits" or "license" for more information. # Create the string >>> f = 'fred' # Look at the string with upper(). This does NOT change the string! >>> f.upper() 'FRED' # Verify the string is unchanged >>> f 'fred' # Set another variable with the uppercase string >>> F = f.upper() >>> F 'FRED' Python is easy to learn and fun to use. You'll progress pretty fast. Leam On 6/23/23 02:22, Jack Simpson wrote: > ---------- Forwarded message --------- > From: Jack Simpson > Date: Fri, 23 Jun 2023 at 1:58 pm > Subject: Re: [Tutor] Beginner struggling with python. > To: dn > > > I tried to use the string.upper() and it returned this syntax error. I also > tried def upper() and upper(). I also tried underscores and spaces within > the string in the parenthesis which produced a similar result but the issue > was with the code within the string. I am on a work computer using an > interpreter so please forgive the photos from my phone. > > On Fri, 23 Jun 2023 at 12:51 pm, dn via Tutor wrote: > >> On 23/06/2023 12.07, Alan Gauld via Tutor wrote: >>> On 22/06/2023 22:45, Jack Simpson wrote: >> ... >> >>>> nicely until we got on to return values and defining functions. Are >>>> particular functions built into python such as def convert( etc. >> >> Yes, Python offers various built-in functions as well as the opportunity >> to write your own "custom functions". >> >> The 'built-ins' include len( string ) which will return the number of >> characters in the string - or number of elements in a "collection" when >> used with a list or similar. >> >> There are also 'functions' which are part of a data-type (class). >> Sticking with strings for the moment: string.upper() will ensure each >> character in that string is converted (where necessary) into >> upper-case/capital-letters. In Python, we use the term "everything is an >> object". So, this function is actually a "method" of the str[ing] >> type/class. There is an important difference between a function and a >> method - a method works on the value to which is is attached, eg >> "string" in this case, whereas a function works independently of any >> specific instance. (see "arguments" and "result" below - but this >> distinction is a bit curly for a beginner) You can tell which you're >> dealing-with, by the 'dotted-notation'. >> >> Then there are the functions you can write yourself, as @Alan has >> described. >> >> >> Noting that functions 'take in' certain (optional) values and return a >> result, the general form is: >> >> def name( arguments ): >> # computation >> return result >> >> The "name" should be a meaningful description of the "computation", ie >> the purpose of the function. >> >> The "arguments" (zero or more) will be a comma-separated list of >> identifiers which are inputs to the function. In @Alan's example, 7, to >> produce the seven times-table or 9 when your math is better than mine... >> >> The "computation" can be anything which Python will do for you. >> Sometimes we use a function to attend to a sub-problem within the wider >> application, ie produces a neatly labelled-result. Another use for >> functions is when we repeat the same "computation" repeatedly, and >> perhaps from different points in the application. >> >> The "result" seems self explanatory. Every function returns a "result". >> If there is a return-statement, that will compute a value. If not, the >> return-value is None. The wording in the singular-form is slightly >> mis-leading. If appropriate, a function can return a collection of >> values, eg a tuple or a list - however it is still only one "collection"! >> >> >> We don't have to def-ine built-in functions (or those which are >> import-ed from a library). >> >> >> The "name( arguments )" and "return result" components are often called >> the "signature" of the function. Basically, the function says: if you >> give me this, I'll give you that by-return. Hah! The "signature" is an >> interface which sets-out all the 'rules' for what you can do with the >> function - remember the len() example (above), its signature allows us >> to apply it to a string or a list (or other "collection"). Flexibility! >> ("polymorphism"). >> >> The "signature" also advises what to expect as a result: OK the 'length' >> part is right there in the function-name, but the signature tells us >> that the return-value will be an integer. Again, not much of a surprise >> given that we are expecting a number, and it is hard to have a string >> with a negative-number of characters or indeed part of a character. >> However, some functions are less obvious and thus the signature is the >> means of ensuring that we use the function for the purpose and in the >> manner its author intended. >> >> In the Python REPL try: help( function_name ) >> Web.Ref: https://docs.python.org/3/library/functions.html#len >> >> >> Using a function is termed "calling a function". As above, this can look >> like: >> >> number_of_characters = len( string ) >> or >> seventh_times_table = times_table( 7 ) >> >> The general form here is: >> >> identifier = function_name( parameters ) >> >> The "signature" is also generalised, but is at-least specific to that >> particular function. >> >> Do we need to document that "function_name" has to correspond to a >> def-statement (either one of our own, or one built-in and provided to us)? >> >> The optional parameters must be provided if the function/signature >> demands. Some may be required. Others may be optional. There is a >> variety of ways these may be expressed (a story for another day). >> >> The function's return-value is passed 'across' the assignment to >> "number_of_characters" or "seventh_times_table" (or passed directly into >> the print() function*). The identifier will become the same data-type as >> the result-data. >> >> * you will have noticed that @Alan uses the function's result within a >> print-call rather than an assignment statement, but we are still making >> use of the return-value. >> >> >> >> (just because this very afternoon, I've been helping someone-else who's >> using it) >> A free-to-download or read-on-the-web book is Al Sweigart's "Automate >> the Boring Stuff". Chapter 3 deals with functions >> (http://automatetheboringstuff.com/2e/chapter3/) >> It's getting a bit old now, but the basics haven't changed... >> >> >> @Alan mentioned online tutorials, quite possibly anticipating that I'd >> chime-in with (an alternate/additional view): the suggestion of online >> courses, eg Coursera, edX, FutureLearn, ... The advantage of these is >> that they usually present their material in both text and video forms, >> plus they collect a community of fellow-trainees, who will help >> each-other with questions and readily-recognise which session/chapter >> you're working at, right now. >> >> (however, re-iterating @Alan's welcome, this Discussion List is also for >> exactly those kinds of discussions) >> >> >> Disclaimer: I use the edX platform - but not for Python training. >> -- >> Regards, >> =dn >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Software Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) From majidbuttm at hotmail.com Fri Jun 23 06:44:59 2023 From: majidbuttm at hotmail.com (majid butt) Date: Fri, 23 Jun 2023 10:44:59 +0000 Subject: [Tutor] Help for Python In-Reply-To: References: Message-ID: Dear Sir/Madam, My name is Majid Butt. I am from Pakistan learning Python 3 for the last two and half years. I have developed a database desktop application using Python and SQLite3. At this point of time, I am able to retrieve data from database as a list of tuples in Python. What i need now is to attach a report template so that i can give retrieved data to this template and generate a report so that i can read the report and take a hard copy print of that report. Could you please provide me the name of a third-party tool (other than Excel & Pdf) from where i can design a template and tell me the code to integrate this template with Python. I am basically designing Ledger reports for an accounting software which requires multi page report. I have been searching internet for the last one year but could not find any solution to it. Please help me I will be very grateful to you. Thanks & Regards Majid Butt Pakistan Mobile # 00923338773001 Sent from Outlook From trent.shipley at gmail.com Fri Jun 23 11:54:21 2023 From: trent.shipley at gmail.com (trent shipley) Date: Fri, 23 Jun 2023 08:54:21 -0700 Subject: [Tutor] Driving a CLI for testing Message-ID: How do I drive a command line interface for a Python script to test that the CLI is working per design? From trent.shipley at gmail.com Fri Jun 23 13:11:13 2023 From: trent.shipley at gmail.com (trent shipley) Date: Fri, 23 Jun 2023 10:11:13 -0700 Subject: [Tutor] Multiple front-ends in project Message-ID: I have written the simple core logic for a dice rolling program. It is In ./app/core. I am planning to add more complex helper classes in separate files to do more complex things like rolling different kinds of dice in one throw, or exploding dice. I plan four interfaces, two CLI, and two GUI. 1. A pretty simple CLI with just the basic core functionality. 2. A small DSL for rolling dice, with support for complexities like using pre-provisioned numpy probability functions and using in one throw, re-rolls if a result is in a certain range and so on. 3. A GUI meeting common requirements for role-playing games. 4. A "Scientific GUI" with some, but not all, of the power of the command line and scriptable DSL. *Buried Lead:* I am now working on #1 the Simple CLI. ** How do I arrange things so I can run ./app/cli/simple_cli/simple_hdroll_cli_main.py as "$ python3 shdroll kwargs"? ** Looking to the future, how do I package and distribute my project so it can be used conveniently on all three OSes per my design intent. (The command line interfaces work like command line commands, The DSL can interpret and run scripts, and the GUIs act like native GUI programs for all three OSes. (I am developing on Linux Mint.)) (venv) trent at trent-virtual-machine:~/pythonworkspace/hackable_dice_roller$ tree --gitignore > ../hdr_tree.txt . ??? app ? ??? cli ? ? ??? dice_dsl ? ? ??? __init__.py ? ? ??? simple_cli ? ? ??? __init__.py ? ? ??? simple_hdroll_cli_main.py ? ? ??? simple_hdroll_cli_parser.py ? ??? core ? ? ??? hackable_dice_roller.py ? ? ??? __init__.py ? ??? gui ? ? ??? scientific_gui ? ? ??? simple_gui ? ??? __init__.py ? ??? tests ? ??? cli ? ? ??? dice_dsl ? ? ??? simple_cli ? ? ??? __init__.py ? ??? core ? ? ??? __init__.py ? ? ??? test_hdr_core.py ? ? ??? test_hdr_core_visually.py ? ??? gui ? ??? scientific_gui ? ??? simple_gui ??? __init__.py 20 directories, N files From alan.gauld at yahoo.co.uk Fri Jun 23 20:20:13 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 24 Jun 2023 01:20:13 +0100 Subject: [Tutor] Help for Python In-Reply-To: References: Message-ID: On 23/06/2023 11:44, majid butt wrote: > > Dear Sir/Madam, > > ...developed a database desktop application using Python and SQLite3.> At this point of time, I am able to retrieve data from database as a list of tuples in Python. Congratulations, that's usually the hardest bit (assuming the data is correct!) > What i need now is to attach a report template so that i can > give retrieved data to this template and generate a report OK, that'ds also pretty standard practice. Usually the report lives in a text file someplace and you read it into your program as needed. > Could you please provide me the name of a third-party tool > (other than Excel & Pdf) from where i can design a template Why nor PDF or Excel? These are excellent data formatting tools and there is support for them from Python? But there are many others. HTML is a common formatting tool these days and you can style it with CSS. > and tell me the code to integrate this template with Python. You will need to create the template itself, no tool can predict what you want to create. There are many templating tools but frankly, for most cases, some basic HTML and CSS will suffice. Pythons built in string formatting features should be sufficient to insert your tuple data into the template string. If HTML is not good enough you can use groff or LaTeX to produce publishing quality output. But ultimately, without sample data and details of what kind of output you need it's impossible for us to give a complete solution. And to be honest we try not to give complete solutions, it's better to give pointers and let you find the full solution yourself. That way you will be able to fix/extend it later. If you can provide more details of the kind of template you need, or explain why HTML/PDF etc can't be used then we'll be happy to help with more suggestions. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Fri Jun 23 20:27:05 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 24 Jun 2023 01:27:05 +0100 Subject: [Tutor] Fwd: Beginner struggling with python. In-Reply-To: References: <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info> Message-ID: On 23/06/2023 08:22, Jack Simpson wrote: > I tried to use the string.upper() and it returned this syntax error. The server strips attachments as security risks. You will need to cut 'n paste the text (or retype it as a last resort) But please explain what you are trying to do. Is it to create your own function to create upper case strings? Or is it to use the builtin function(strictly speaking a method of the string class) Show us before and after data(what you want to do) Show us sample code (how you tried to do it) Show us any error messages (what Python thought of your code) > tried def upper() and upper(). Those are two entirely different things. How you tried them should have been different too. But we can't tell. > I also tried underscores and spaces within > the string in the parenthesis which produced a similar result but the issue > was with the code within the string. That makes no sense whatsoever until you show us. underscores and spaces should have absolutely no effect in uppercase transformations. > I am on a work computer using an > interpreter so please forgive the photos from my phone. I assume that means you took photos of your work computer with your phone? Can you not send text email from your work computer? That would allow you to paste code/errors etc into the email. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Fri Jun 23 20:33:09 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 24 Jun 2023 01:33:09 +0100 Subject: [Tutor] Driving a CLI for testing In-Reply-To: References: Message-ID: On 23/06/2023 16:54, trent shipley wrote: > How do I drive a command line interface for a Python script to test that > the CLI is working per design? There are test frameworks for python but one of the easiest ways for a CLI is to use file redirection OS> python3 myprogram.py testN_output.txt testN_input.txt then contains all the input strings required to run the testN scenario. The results will be captured in testN_output.txt and can be compared to the expected output (stored in, say, testN_results.txt) If the files testN_results.txt and testN_output.txt are identical then the test passes. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Fri Jun 23 20:50:40 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 24 Jun 2023 01:50:40 +0100 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: Message-ID: On 23/06/2023 18:11, trent shipley wrote: > I have written the simple core logic for a dice rolling program. It is In > ./app/core. I am planning to add more complex helper classes in > separate files to do more complex things like rolling different kinds of > dice in one throw, or exploding dice. > > I plan four interfaces, two CLI, and two GUI. When you say "interfaces" I assume you mean user interfaces? Or do you include an API so that other programmers can use your code too? If we restrict ourselves to user interfaces, did you design your code to follow the MVC pattern? If so, it should be easy to implement VC classes for each type of UI, and also Web or network interfaces if needed later. If you didn't use an MVC architecture then you should probably rework the core code to be a model that can speak to views and controllers. It will make life much easier for everyone. > 1. A pretty simple CLI with just the basic core functionality. > 2. A small DSL for rolling dice, with support for complexities like > using pre-provisioned numpy probability functions and using in one throw, > re-rolls if a result is in a certain range and so on. > 3. A GUI meeting common requirements for role-playing games. > 4. A "Scientific GUI" with some, but not all, of the power of the > command line and scriptable DSL. That is a combination of vague waffle and domain specific gobbledegook. We can't possibly guess what that means. > *Buried Lead:* > I am now working on #1 the Simple CLI. ** How do I arrange things so I can > run ./app/cli/simple_cli/simple_hdroll_cli_main.py as "$ > python3 shdroll kwargs"? ** Create an alias on your OS? > Looking to the future, how do I package and distribute my project so it can > be used conveniently on all three OSes per my design intent. Which three OS? There are many more than 3 OS in the world. Which OS do you have in mind? I'll take a guess at Windows and MacOS Cocoa as two? The third could be web(and thee are several options there?!), CLI, Posix, Unix/CDE, Linux(which desktop>?), MVS, VMS, etc, etc. (The command > line interfaces work like command line commands, The DSL can interpret and > run scripts, and the GUIs act like native GUI programs for all three OSes. > (I am developing on Linux Mint.)) Even stating Linux Mint still leaves us guessing over desktop - Cinnamon, Mate, LXDE, etc? User interfaces are very specific things. You can't even just say GUI. There are many GUI frameworks and they are all quite different. Are you using Tkinter, wxPython, pyGTK, Side, or the native toolkits for each OS - Windows MFC(via pythonwin) or the .NET framework - possibly via IronPython?! Or Cocoa on MacOS? Or Java Swing using jython - that would be cross OS, and work on much more than 3 OS. -- 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 mk1853387 at gmail.com Sat Jun 24 05:28:38 2023 From: mk1853387 at gmail.com (marc nicole) Date: Sat, 24 Jun 2023 11:28:38 +0200 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? Message-ID: I want to get the 100th greatest number in an array of one billion elements. How to do that efficiently? I was thinking of dividing the original array into smaller arrays and then get the biggest number in each of them and then compare with others etc... But any better ideas here? Thanks. From alan.gauld at yahoo.co.uk Sat Jun 24 18:40:44 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 24 Jun 2023 23:40:44 +0100 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: References: Message-ID: On 24/06/2023 10:28, marc nicole wrote: > I want to get the 100th greatest number in an array of one billion > elements. How to do that efficiently? I was thinking of dividing the > original array into smaller arrays and then get the biggest number in each > of them and then compare with others etc... But any better ideas here? I suspect the most efficient is probably using the builtin max() function, unless... You get into threading or another concurrency mechanism. In that case splitting your list into N chunks and assigning the max() to different threads and then bringing the N, results together into a single call to max might be faster. But on my M1 Mac it took less than 90 seconds for a billion item list using vanilla max(). If 90s is too long then by all means try concurrency. -- 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 mk1853387 at gmail.com Sat Jun 24 19:07:36 2023 From: mk1853387 at gmail.com (marc nicole) Date: Sun, 25 Jun 2023 01:07:36 +0200 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: References: Message-ID: sry, I want to get 100 greatest elements (not the 100th element) Le dim. 25 juin 2023 ? 00:42, Alan Gauld via Tutor a ?crit : > On 24/06/2023 10:28, marc nicole wrote: > > I want to get the 100th greatest number in an array of one billion > > elements. How to do that efficiently? I was thinking of dividing the > > original array into smaller arrays and then get the biggest number in > each > > of them and then compare with others etc... But any better ideas here? > > I suspect the most efficient is probably using the > builtin max() function, unless... You get into threading > or another concurrency mechanism. > > In that case splitting your list into N chunks > and assigning the max() to different threads and > then bringing the N, results together into a > single call to max might be faster. > > But on my M1 Mac it took less than 90 seconds for a billion > item list using vanilla max(). If 90s is too long then by > all means try concurrency. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Sat Jun 24 20:23:23 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 25 Jun 2023 01:23:23 +0100 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: References: Message-ID: On 25/06/2023 00:07, marc nicole wrote: > sry, I want to get 100 greatest elements (not the 100th element) Oops! Sorry I completely misread the requirement. My first response would be to convert the list to a set(to remove duplicates - although you may want to include duplicates, you don't specify), sort the set and pick out the 100th element from the end. I'm sure there are cleverer algorithms but I'd try the simple approach first and see if it's fast enough. I'd also look at how you build the list in the first case, is it possible to build it in sorted order? Often creating a sorted list initially is faster overall than building a random list then sorting it. Thinking about concurrent solutions you would need to collect the 100 highest members for each sublist you created. Then merge/sort the groups of 100 and pick out the 100th overall. If you have a relatively small set of sublists, say 100, each with 10million members then merging/sorting 100x100 may well be faster than sorting 1 billion. But timing it to check will be critical. But threading 100 process intensive instances may well lead to its own issues and moving to async or multi-tasking is likely to be slower too. A lot of experimentation and testing will be needed I suspect. -- 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 threesomequarks at proton.me Sat Jun 24 21:34:09 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Sun, 25 Jun 2023 01:34:09 +0000 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: References: Message-ID: Alan has some good suggestions and it obviously depends on your data and requirements. Before I say more, you did not specify what this was for. If it is a classroom assignment, the best solution may relate to what was taught in class. That may well mean not using some data structures and modules and using what you are supposed to know at this point. But first, in any case, make sure you completely understand what the data looks like and what details about the answer apply. Some algorithms will not provide what you want, otherwise. Do you need the 100 extreme numbers exactly and in order including duplicates? Are the numbers all integers or can they be floating point, or even complex, or something like Decimal or can they contain negative numbers, or empty numbers or even infinity? You may need to preprocess all the billion numbers before beginning whatever algorithm you choose. As an example, Inf may have to be replaced with some maximum number, and floating point may need to be truncated or rounded and text may need to be converted to a number format like the rest. GIGO. If there are duplicates, do you want all copies collapsed into one and the remaining 100 most extreme returned in perhaps any order? Alan suggested just converting the numbers into a set and presumably this smaller set of numbers could be easier to work with such as just sorting it. This may not work unless all you have are integers and even then it has problems like not keeping duplicates if that is required. Using a dictionary where the value keeps track of how many of each, might be a way to go then. Breaking it into smaller groups also may be imperfect. There may be multiple solutions within each group. As Alan points out, you would need to keep 100 from each and merge that and then keep the last. Sorting as in a merge sort might be interesting but for a billion items still a tad expensive. Assuming you want duplicates for now. You would want a modified merge sort such as a binary version that splits the current region of the data in roughly two as long as the size is no less than 100 or 50 and then stop and start returning a sorted answer. The merge part would take only 100 best results and pass those back and ignore the rest. Each merge on the way back up would only return 100 so when you get to the top, you have your answer If you wanted to do this in parallel, that gets a tad harder. And there is of course the simple-minded approach. Find the largest number in a linear search and add it to your results list and remove it from the billion or perhaps mark a location in a set of offsets to be ignored. Repeat 99 times. Too many other ways are possible such as creating a tree (perhaps binary) until you have a billion entries and then traverse the tree till you get 100. I won't provide it, but if this is for your own use, there are modules you can load that do what you asked of getting the top N. You can search for those but obviously a homework using those defeats the purpose. - Q Sent with Proton Mail secure email. ------- Original Message ------- On Saturday, June 24th, 2023 at 8:23 PM, Alan Gauld via Tutor wrote: > On 25/06/2023 00:07, marc nicole wrote: > > > sry, I want to get 100 greatest elements (not the 100th element) > > > Oops! Sorry I completely misread the requirement. > > My first response would be to convert the list to a set(to remove > duplicates - although you may want to include duplicates, you don't > specify), sort the set and pick out the 100th element from the end. > > I'm sure there are cleverer algorithms but I'd try the simple > approach first and see if it's fast enough. > > I'd also look at how you build the list in the first case, > is it possible to build it in sorted order? Often creating > a sorted list initially is faster overall than building a > random list then sorting it. > > Thinking about concurrent solutions you would need to collect > the 100 highest members for each sublist you created. Then > merge/sort the groups of 100 and pick out the 100th overall. > If you have a relatively small set of sublists, say 100, > each with 10million members then merging/sorting 100x100 may > well be faster than sorting 1 billion. But timing it to > check will be critical. But threading 100 process intensive > instances may well lead to its own issues and moving to > async or multi-tasking is likely to be slower too. A lot of > experimentation and testing will be needed I suspect. > > -- > 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 threesomequarks at proton.me Sat Jun 24 21:50:53 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Sun, 25 Jun 2023 01:50:53 +0000 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: References: Message-ID: <9y_xHCYpGihjwMV3PVItWaTzFKtprtTW_VWTbwN74lC3Wu_IMdPobl9bHNHLkFFyG-2MTBe-TKuH0AfB4x9r5VckUr3fUiS-fNSdlqpwu8E=@proton.me> I am wondering if a sliding window protocol is a suitable way to find the top 100. The outline would be like this. Create a data structure that hold 100 items and also keeps track of the current smallest item. Begin by copying the first 100 of your billion numbers to the structure which could be several variables or an object you created. If ignoring duplicates, add as many as it takes to get exactly 100 unique items. Using a set might be a good idea. Either way, you now have a variable containing the smallest item value. Then iterate on all remaining items one at a time. If the item is not already in the list (assuming no duplicates) and the item is greater than the minimum, then replace the minimum with the new item and update the new minimum to whatever is now the smallest. You can keep the context sorted or not. When you have processed the billion values, process the 100 to be displayed in whatever way you want. If you generalize the above to do the top N, you may also want to make sure you handle cases like what happens if you have less than N unique results and also deal with my previous comments that all the numbers are valid and perhaps deal with cases like inf. This solution only scans the list once so it may be fairly fast as long as the processing per item is not slow. - Q Sent with Proton Mail secure email. ------- Original Message ------- On Saturday, June 24th, 2023 at 9:34 PM, ThreeBlindQuarks wrote: > Alan has some good suggestions and it obviously depends on your data and requirements. > > Before I say more, you did not specify what this was for. If it is a classroom assignment, the best solution may relate to what was taught in class. That may well mean not using some data structures and modules and using what you are supposed to know at this point. > > But first, in any case, make sure you completely understand what the data looks like and what details about the answer apply. Some algorithms will not provide what you want, otherwise. > > Do you need the 100 extreme numbers exactly and in order including duplicates? > > Are the numbers all integers or can they be floating point, or even complex, or something like Decimal or can they contain negative numbers, or empty numbers or even infinity? You may need to preprocess all the billion numbers before beginning whatever algorithm you choose. As an example, Inf may have to be replaced with some maximum number, and floating point may need to be truncated or rounded and text may need to be converted to a number format like the rest. GIGO. > > If there are duplicates, do you want all copies collapsed into one and the remaining 100 most extreme returned in perhaps any order? > > Alan suggested just converting the numbers into a set and presumably this smaller set of numbers could be easier to work with such as just sorting it. This may not work unless all you have are integers and even then it has problems like not keeping duplicates if that is required. Using a dictionary where the value keeps track of how many of each, might be a way to go then. > > Breaking it into smaller groups also may be imperfect. There may be multiple solutions within each group. As Alan points out, you would need to keep 100 from each and merge that and then keep the last. > > Sorting as in a merge sort might be interesting but for a billion items still a tad expensive. Assuming you want duplicates for now. You would want a modified merge sort such as a binary version that splits the current region of the data in roughly two as long as the size is no less than 100 or 50 and then stop and start returning a sorted answer. The merge part would take only 100 best results and pass those back and ignore the rest. Each merge on the way back up would only return 100 so when you get to the top, you have your answer > > If you wanted to do this in parallel, that gets a tad harder. > > And there is of course the simple-minded approach. Find the largest number in a linear search and add it to your results list and remove it from the billion or perhaps mark a location in a set of offsets to be ignored. Repeat 99 times. > > Too many other ways are possible such as creating a tree (perhaps binary) until you have a billion entries and then traverse the tree till you get 100. > > I won't provide it, but if this is for your own use, there are modules you can load that do what you asked of getting the top N. You can search for those but obviously a homework using those defeats the purpose. > > - Q > > Sent with Proton Mail secure email. > > > ------- Original Message ------- > On Saturday, June 24th, 2023 at 8:23 PM, Alan Gauld via Tutor tutor at python.org wrote: > > > > > On 25/06/2023 00:07, marc nicole wrote: > > > > > sry, I want to get 100 greatest elements (not the 100th element) > > > > Oops! Sorry I completely misread the requirement. > > > > My first response would be to convert the list to a set(to remove > > duplicates - although you may want to include duplicates, you don't > > specify), sort the set and pick out the 100th element from the end. > > > > I'm sure there are cleverer algorithms but I'd try the simple > > approach first and see if it's fast enough. > > > > I'd also look at how you build the list in the first case, > > is it possible to build it in sorted order? Often creating > > a sorted list initially is faster overall than building a > > random list then sorting it. > > > > Thinking about concurrent solutions you would need to collect > > the 100 highest members for each sublist you created. Then > > merge/sort the groups of 100 and pick out the 100th overall. > > If you have a relatively small set of sublists, say 100, > > each with 10million members then merging/sorting 100x100 may > > well be faster than sorting 1 billion. But timing it to > > check will be critical. But threading 100 process intensive > > instances may well lead to its own issues and moving to > > async or multi-tasking is likely to be slower too. A lot of > > experimentation and testing will be needed I suspect. > > > > -- > > 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 simpsonrmz41 at gmail.com Sun Jun 25 02:20:15 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Sun, 25 Jun 2023 16:20:15 +1000 Subject: [Tutor] Unexpected name error Message-ID: Hi, I am playing around with the if, elif, else statements and can't figure out why I am getting this name error when I have defined the value of x. Any pointers would be great. >>> if x>7: ... print(x is positive) ... elif x>12: ... print(x is negative) ... else: ... print(x is str(0)) ... x=15 ... Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined From simpsonrmz41 at gmail.com Sun Jun 25 03:05:46 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Sun, 25 Jun 2023 17:05:46 +1000 Subject: [Tutor] Uses for backslashes Message-ID: Hi, I'm going through some quizzes and tutorials in a coding course I am completing and these backslashes are being used in some lines of code. I have researched and have found that it changes the meaning of the following character i.e. \n is a line feed, \t is a new tab but I can"t find why it is used in a case like this. Thanks for your help. var1 = "my computer" >= "my chair" var2 = "Spring" <= "Winter" var3 = "pineapple" >= "pineapple" print("Is \"my computer\" greater than or equal to \"my chair\"? Result: " , var1) print("Is \"Spring\" less than or equal to \"Winter\"? Result: ", var2) print("Is \"pineapple\" less than or equal to \"pineapple\"? Result: " , var3) From alan.gauld at yahoo.co.uk Sun Jun 25 03:51:44 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 25 Jun 2023 08:51:44 +0100 Subject: [Tutor] Unexpected name error In-Reply-To: References: Message-ID: On 25/06/2023 07:20, Jack Simpson wrote: > Hi, > > I am playing around with the if, elif, else statements and can't figure out > why I am getting this name error when I have defined the value of x. Any > pointers would be great. > >>>> if x>7: > ... print(x is positive) You need to put quote signs around the thing you want to print. Without quotes Python tries to evaluate the contents of the brackets as code and since there is no variable called x it gives a name error. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sun Jun 25 04:02:35 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 25 Jun 2023 09:02:35 +0100 Subject: [Tutor] Uses for backslashes In-Reply-To: References: Message-ID: On 25/06/2023 08:05, Jack Simpson wrote: > following character i.e. \n is a line feed, \t is a new tab but I can"t > find why it is used in a case like this. Thanks for your help. > > var1 = "my computer" >= "my chair" > > print("Is \"my computer\" greater than or equal to \"my chair\"? Result: " > , var1) This is called escaping a character. It tells Python to treat the next character as a literal character and ignore its special meaning. ie. it prints the quote sign rather that treating it as the end of the string. Without the quotes Python would see: A short string: "Is " two unquoted words: my computer Another short string: " greater than or equal to " Another two words: my chair Another short string "? Result: " The unquoted words make no sense to Python so in reality you'd get an error, hence the need for the \" notation. However, this is very unusual practice in Python. Because Python has multiple ways of quoting strings it's far more common to surround the outer string with a different quote sign: 'Is "my computer" greater than or equal to "my chair"? Result: ' By using single quotes to define the string limits we are free to use double quotes inside. And if the string contains both double and single quotes(an apostrophe say) then we can surround the string with triple quotes: '''I'd like to teach the world to sing "Amazing Grace"''' Your tutorial is technically correct in showing that use of \ but in practice it is only occasionally seen. Mostly in something called a regular expression which you probably haven't covered yet. -- 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 threesomequarks at proton.me Sun Jun 25 09:11:02 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Sun, 25 Jun 2023 13:11:02 +0000 Subject: [Tutor] Uses for backslashes In-Reply-To: References: Message-ID: Welcome Jack, I see Alan has answered both of your questions. I note both questions you ask suggest you should look into some of the many ways Python represents strings. There are quite a few flavors that can be chosen based on convenience and taste. Since you seem to be taking a course of sorts, it probably is explaining quite a bit and the examples often are there to illustrate. But note that many coders would rarely use a backslash to mask a quote character as there are other ways. If you know you will want actual double quotes in a string then you can use single quotes to delineate the string and any double quotes inside it are now unambiguous. Or you can use triples of either single or double quotes before/after and anything inside that is not the same triple is left alone. There are other ways. And note the backslash is used for MANY things and some code with strings that may be repeatedly evaluated may have \\ and even \\\\ in it. Each language has conventions and you just have to get used to the rules. - Q Sent with Proton Mail secure email. ------- Original Message ------- On Sunday, June 25th, 2023 at 3:05 AM, Jack Simpson wrote: > Hi, > > I'm going through some quizzes and tutorials in a coding course I am > completing and these backslashes are being used in some lines of code. I > have researched and have found that it changes the meaning of the > following character i.e. \n is a line feed, \t is a new tab but I can"t > find why it is used in a case like this. Thanks for your help. > > var1 = "my computer" >= "my chair" > > var2 = "Spring" <= "Winter" > var3 = "pineapple" >= "pineapple" > > > print("Is \"my computer\" greater than or equal to \"my chair\"? Result: " > , var1) > print("Is \"Spring\" less than or equal to \"Winter\"? Result: ", var2) > print("Is \"pineapple\" less than or equal to \"pineapple\"? Result: " > , var3) > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From mats at wichmann.us Sun Jun 25 13:37:23 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 25 Jun 2023 11:37:23 -0600 Subject: [Tutor] Any ideas on designing an efficient algorithm for this problem? In-Reply-To: <9y_xHCYpGihjwMV3PVItWaTzFKtprtTW_VWTbwN74lC3Wu_IMdPobl9bHNHLkFFyG-2MTBe-TKuH0AfB4x9r5VckUr3fUiS-fNSdlqpwu8E=@proton.me> References: <9y_xHCYpGihjwMV3PVItWaTzFKtprtTW_VWTbwN74lC3Wu_IMdPobl9bHNHLkFFyG-2MTBe-TKuH0AfB4x9r5VckUr3fUiS-fNSdlqpwu8E=@proton.me> Message-ID: On 6/24/23 19:50, ThreeBlindQuarks via Tutor wrote: > > I am wondering if a sliding window protocol is a suitable way to find the top 100. That's not a bad approach. There's also an algorithm already in the standard library: heapq.nlargest(100, array) whether that's optimal for a billion records, I don't know, but the heap sorting approach is usually considered pretty efficient. From PythonList at DancesWithMice.info Sun Jun 25 18:32:08 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 10:32:08 +1200 Subject: [Tutor] Unexpected name error In-Reply-To: References: Message-ID: On 25/06/2023 18.20, Jack Simpson wrote: > Hi, > > I am playing around with the if, elif, else statements and can't figure out > why I am getting this name error when I have defined the value of x. Any > pointers would be great. > >>>> if x>7: > ... print(x is positive) > ... elif x>12: > ... print(x is negative) > ... else: > ... print(x is str(0)) > ... x=15 > ... > Traceback (most recent call last): > File "", line 1, in > NameError: name 'x' is not defined Additionally, (info missing) was x given a value before the if-construct? -- Regards, =dn From PythonList at DancesWithMice.info Sun Jun 25 19:44:30 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 11:44:30 +1200 Subject: [Tutor] Uses for backslashes In-Reply-To: References: Message-ID: <4b99b88a-6a30-9000-affe-3ba3e293933d@DancesWithMice.info> On 25/06/2023 19.05, Jack Simpson wrote: > Hi, > > I'm going through some quizzes and tutorials in a coding course I am > completing and these backslashes are being used in some lines of code. I > have researched and have found that it changes the meaning of the > following character i.e. \n is a line feed, \t is a new tab but I can"t > find why it is used in a case like this. Thanks for your help. > > var1 = "my computer" >= "my chair" > var2 = "Spring" <= "Winter" > var3 = "pineapple" >= "pineapple" > > print("Is \"my computer\" greater than or equal to \"my chair\"? Result: " > , var1) > print("Is \"Spring\" less than or equal to \"Winter\"? Result: ", var2) > print("Is \"pineapple\" less than or equal to \"pineapple\"? Result: " > , var3) "I can"t find why it is used in a case like this." What happened when the code was executed? What was the appearance of the output? It seems that you have been using the Python-REPL. These questions are exactly its purpose - to experiment, to prototype, to check/test one's understanding or recollection... Such is the opposite of the ?good, old, days when "turn-around" took so long that experimenting was very expensive. So, we researched the theory and asked questions first ... "Escape Sequences in Python" (https://www.freecodecamp.org/news/escape-sequences-python/) this article is a gentle introduction to escaping characters. NB further to @Alan (maybe I didn't notice) and perhaps because we generally eschew the use of Regular Expressions (RegEx[p]), the other most common use for back-slashes (that we see) is from the one or two colleagues who seem to like using them for line-continuation purposes. (I think it ugly, but then they don't like having to open (and close) greater numbers of parentheses - so, opinions vary...) There's a bit of a 'cheat sheet' in "Escape Characters" (https://python-reference.readthedocs.io/en/latest/docs/str/escapes.html), which may help to highlight the (likely) few escape codes you'll ever (want to) use. Which brings me to extend the observation about 'ugly' (above) - I find the use of back-slash escaped-characters within code-blocks not only ugly, but one of those things that cause these aged-eyes to struggle. In short, they fall into a category called "magic numbers" (or, in this case, "magic strings"). Received-wisdom is to 'lift' constants (the Python term is "literals") from inside the code to 'the top' - in the same way as PEP-008 recommends we do the same for import-statements. The reason is that when such values are required to change (and the client will inevitably come to 'change the rules [supposedly cast in stone]' one day!) it is quite a job to search through an entire code-base - and to be sure that you have found every last place where such might be used. Accordingly, the solution illustrated in the web.ref: - at the top of the code/in a separate config file (if used), define: NEWLINE = "\n" # or chr( 10 )* - then within the code, use the literal-identifier: print( F"{name}{NEWLINE}{rank}{NEWLINE}{serial_number}" ) or print( name, rank, serial_number, sep=NEWLINE ) (not sure if your course has covered F-strings - or print()'s sep-argument for that matter) * TBH when I first started in computing (after my pet-dinosaur grew too big to play-with) most of us memorised the 'blocks' of ASCII-code (and IBM mainframe EBCDIC), so I still think of NEWLINE (or rather, LINE-FEED) as integer-10. Also, if writing it, rather than the full-word, using the abbreviations mentioned in that document (eg "LF"). So, the encouragement to use the full-word is a little "do as I say, not as I do". Hah! BTW the only ones I can remember using recently have been LF and TAB. On MS-Windows CR (or CR + LF) may be applicable. Can't recall using the others (in the ASCII context). Where 'things have changed' is when clients want to use various Unicode characters. Two recent examples involved 'decorating' data in degrees (curiously, one client recording temperature and the other talking lat-long locations). DEGREES = "\u00B0" # ie ?-symbol Again, (mea culpa!) I tend to 'cheat' (and prefer the more illustrative/easier to comprehend approach) by copying the character from somewhere else (my Linux OpSys offers a "Character Map" application which enables searching for characters or scanning for what is required): DEGREES = "?" Enough? More on this, eg https://www.fileformat.info/info/unicode/char/2103/index.htm If you're a glutton-for-punishment, the docs which were generated when Python moved from an ASCII to a Unicode 'encoding' were distilled into https://docs.python.org/3/howto/unicode.html#the-string-type Very complicated for a beginner, but if you'd like to dive 'into the weeds' of Python's definitions: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -- Regards, =dn From PythonList at DancesWithMice.info Sun Jun 25 19:49:35 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 11:49:35 +1200 Subject: [Tutor] Help for Python In-Reply-To: References: Message-ID: On 23/06/2023 22.44, majid butt wrote: > What i need now is to attach a report template so that i can give retrieved data to this template and generate a report so that i can read the report and take a hard copy print of that report. Could you please provide me the name of a third-party tool (other than Excel & Pdf) from where i can design a template and tell me the code to integrate this template with Python. I am basically designing Ledger reports for an accounting software which requires multi page report. 3 Python template libraries compared Does your next Python project need a templating engine to automatically generate HTML? Here are a few options. By Jason Baker April 27, 2018 | 5 min read https://opensource.com/resources/python/template-libraries The one I've used most-often: https://pypi.org/project/Jinja2/ Python.org's wiki page (hasn't been updated in years) https://wiki.python.org/moin/Templating -- Regards, =dn From PythonList at DancesWithMice.info Sun Jun 25 20:02:04 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 12:02:04 +1200 Subject: [Tutor] Fwd: Beginner struggling with python. In-Reply-To: References: <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info> Message-ID: <9959be39-f0b0-8fc9-2886-53adb27c1df1@DancesWithMice.info> On 23/06/2023 19.22, Jack Simpson wrote: > ---------- Forwarded message --------- > From: Jack Simpson > Date: Fri, 23 Jun 2023 at 1:58 pm > Subject: Re: [Tutor] Beginner struggling with python. > To: dn > > > I tried to use the string.upper() and it returned this syntax error. I also > tried def upper() and upper(). I also tried underscores and spaces within > the string in the parenthesis which produced a similar result but the issue > was with the code within the string. I am on a work computer using an > interpreter so please forgive the photos from my phone. Boy was I surprised to see a photo in a list-email! - until I realised you had also sent a personal copy (directly) to me... Suspect that you're only showing us part of the problem (also other messages). Please see @Alan's sage advice. In this case, one must first define the string's value, and only thereafter apply the upper() method (function). First build the house, then apply the paint (change its appearance)! (example in @Leam's response). Apologies if the earlier explanation was unclear. In books and docs different fonts are used to differentiate between "string" as an identifier and "string" as a generic term/Python data-type. In email, not so easy! Accordingly, you could use any string-identifier, not only the word "string" - per @Leam's "f" identifier (which is a string data-type or object). As he says, Python is fun to learn, and reasonably straight-forward. Keep ploughing-ahead. Like any other 'learning-curve', there's even more fun 'just around the bend...'! -- Regards, =dn From PythonList at DancesWithMice.info Sun Jun 25 20:33:21 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 12:33:21 +1200 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: Message-ID: <3dfb4f8f-81f1-d6e4-4a1b-451d7cf4ce84@DancesWithMice.info> On 24/06/2023 12.50, Alan Gauld via Tutor wrote: > On 23/06/2023 18:11, trent shipley wrote: >> I have written the simple core logic for a dice rolling program. It is In >> ./app/core. I am planning to add more complex helper classes in >> separate files to do more complex things like rolling different kinds of >> dice in one throw, or exploding dice. >> >> I plan four interfaces, two CLI, and two GUI. Further to @Alan's analysis, (although not being aware of your level of ComSc/DataSc expertise) I regularly remind/put the 'circles' diagram in front of trainees (https://blog.cleancoder.com/uncle-bob/images/2012-08-13-the-clean-architecture/CleanArchitecture.jpg) This illustrates that the code fulfilling the purposes of the outer 'circles' needs to know (a limited amount of) what's going-on 'inside', but the inner-circle(s) don't need to know where data is coming-from or going-to! (paralleling @Alan's "MVC" ideas of 'separation') If interested, please see-also theories such as "Separation of Concerns" and the "SOLID Principles", specifically the "Single Responsibility Principle". In short, if the description of the work performed by a single unit of code (eg function, class, ...) features the word "and", then that code may contain a 'gotcha' for exercises such as this! Accordingly, the code which actually includes a call to the random-library does not need to know if the request has come from a user using a GUI or the CLI. Yes, other 'outer' logic can take care of that - and ensure that a request from the GUI will return the results in similar fashion rather than printing to the 'command-line'. Considering the 'center' in a bit more detail: what data does the 'core logic' require from its "External Interface" (regardless of which one)? This may include: - how many sides to the die/dice - how many dice - home many rolls ... This is the "API" (Application Programming Interface). More prosaically, it is probably the 'signature' of one of the existing functions in the system. (which is another way of getting rid of the high-falutin terminology) Once you've identified ("finalised") this, then turn your attention to the GUI and CLI components. The 'input' part of these must be built to be as pretty and/or as workable as is appropriate, but ultimately must provide the information required by the (above) API/signature. The same, in-reverse, for output... Referring back to the diagram. The die/dice is an "entity". The number of sides per die is a "business rule" (the 'business' (ahem) of statistical distribution). The "Use Cases" are the varieties of simulations you'd like the dice to be used to perform. The Web/UI/External Interfaces encompass many of your existing explanations/intent. Have enjoyed considering the question. Some additional comment (FWIW): Further to @Alan's "waffle", may I recommend the "YAGNI Principle", ie don't 'put stuff in' until you actually receive a solid use-case for it (in my case: I don't do things until the client has agreed to pay for them). Just because it might be useful - or might be fun to code-up, is not a solid reason (it *is* a reason (professional responsibility?) to go back to the client and ask if (s)he agrees - *and* is prepared to pay for it!). Most of the time it represents a delay to 'delivery' because You/They Ain't Going To Need It! Am also anticipating you will have to put in some 'rework'. Recommend that you start with (unless you have them already) a set of tests (a 'testing framework'). This will 'prove' (in the logic/mathematical sense) that the existing code works correctly. This is a 'stable state'. Now, when something is 'reworked' in order to separate the components and create the API (between External Interfaces and the Entities and Use Cases/Controllers), the tests will continue to pass - or will fail and thereby show that the 'new work' has introduced an error (which, one way or the other) will need 'fixing'! It seems like more (even, unnecessary) work up-front, but may pay greater dividends over time... Looking forward to hearing how the project progresses... -- Regards, =dn From yjhuang at whiteboxtechnologies.com Mon Jun 26 00:58:09 2023 From: yjhuang at whiteboxtechnologies.com (Joe Huang) Date: Sun, 25 Jun 2023 21:58:09 -0700 Subject: [Tutor] Need help in understanding why I'm now getting a SyntaxError on a previously working code Message-ID: This is my first post on tutor at python.org. I have 30+ years in scientific programming, but it was all in Fortran and awk, never in python which I heard of only towards the end of my employment at a national laboratory which I left in 2007.? However, in my private venture since I've found it increasingly necessary to use python for tasks such as downloading data from the Web by calling an API. Fortunately, my son is very familiar with python and had helped me write such a script that was working when I last used it in April. Unfortunately, when I tried using it again today, I got this SyntaxError that's got me stumped: ? File "wkg_API_points.py", line 33 ??? filename = f"{locname}_{latitude}_{longitude}_{start}-{end}_CERES.txt" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ^ SyntaxError: invalid syntax My suspicion is that I might be using an outdated version, since I dimly remember having to update python before I ran the script back in April.? But then I don't understand why the python I'm now calling has suddenly gone back to an earlier version, i.e., Python 2.7.? Since I'm very unfamiliar with python syntax, I thought I'd best ask someone who knows python what the problem really and how I can fix it. The complete code is attached along with a sample input file with 7 locations.? If anyone's curious what this code is supposed to do, it retrieves synthetic weather data for any location on earth just by giving the latitude, longitude, and time period. I see two possible options to solve this problem:? (1) if it is a problem due to the python version,? I would need to find what happened to my Python 3.X ?? (2) if it's a generic syntax error, please tell me what that line should be? Thanks. Incidentally, my son is now on travel abroad, so I don't want to bother him with this little question. Joe -- Joe Huang (Huang rhymes with long) White Box Technologies, Inc. 346 Rheem Blvd., Suite 205A Moraga CA 94556 yjhuang at whiteboxtechnologies.com http://weather.whiteboxtechnologies.com for simulation-ready weather data (o) (925)388-0265 (c) (510)928-2683 -------------- next part -------------- ''' *Version: 2.0 Published: 2021/03/09* Source: [NASA POWER](https://power.larc.nasa.gov/) POWER API Multi-Point Download This is an overview of the process to request data from multiple data points from the POWER API. ''' import os, json, requests def readFile(filename): f = open(filename, "r+") lines = f.read().split("\n") f.close() result = [] for line in lines: if len(line) <= 3: break else: pieces = line.split(" ") pieces_abbr = [x for x in pieces if x != ''] result.append(pieces_abbr) return result locations = readFile("wkg_API_inp.txt") output = r"" base_url = r"https://power.larc.nasa.gov/api/temporal/hourly/point?parameters=ALLSKY_SFC_SW_DWN,ALLSKY_SFC_SW_DNI,SZA,ALLSKY_SFC_LW_DWN&community=RE&longitude={longitude}&latitude={latitude}&start=20{start}0101&end=20{end}1231&format=ASCII" for locname, latitude, longitude, start, end in locations: api_request_url = base_url.format(longitude=longitude, latitude=latitude, start=start, end=end) filename = f"{locname}_{latitude}_{longitude}_{start}-{end}_CERES.txt" response = requests.get(url=api_request_url, verify=True, timeout=30.00) f = open(filename,"w+") #f = open("test.txt") #f.write('\n'.join(response.content.decode('utf-8').split("\n")[25:])) f.write(response.content.decode('utf-8')) f.flush() f.close() #print(f"We just finished doing the file {latitude}_{longitude}") #content = json.loads(response.content.decode('utf-8')) #filename = response.headers['content-disposition'].split('filename=')[1] #filepath = os.path.join(output, filename) #with open(filepath, 'w') as file_object: #json.dump(content, file_object) print("Finished writing to this file: "+filename) -------------- next part -------------- MS_UNIVERSITY-OXFORD_720541 34.383 -89.550 20 22 QC_MCTAVISH_716120 45.500 -73.567 20 22 QC_MONTREAL-ST-HUBERT_713710 45.517 -73.417 20 22 QC_MONTREAL-IAP_716270 45.467 -73.733 20 22 QC_MONTREAL-IAP-MIRABEL_719050 45.683 -74.033 20 22 PA_PHILADEPHIA-IAP_724040 39.873 -75.227 21 22 VA_WASHINGTON-REAGAN-AP_724050 38.847 -77.035 21 22 From PythonList at DancesWithMice.info Mon Jun 26 04:32:16 2023 From: PythonList at DancesWithMice.info (dn) Date: Mon, 26 Jun 2023 20:32:16 +1200 Subject: [Tutor] Need help in understanding why I'm now getting a SyntaxError on a previously working code In-Reply-To: References: Message-ID: <4da6f490-ba1c-ad07-48bb-b0d14539d01b@DancesWithMice.info> On 26/06/2023 16.58, Joe Huang wrote: > This is my first post on tutor at python.org. I have 30+ years in > scientific programming, but it was all in Fortran and awk, never in Welcome! Yes, many of us have fond memories of FORTRAN. Indeed there are places where Python and FORTRAN interact. > Unfortunately, when I tried using it again today, I got this SyntaxError > that's got me stumped: > > ? File "wkg_API_points.py", line 33 > ??? filename = f"{locname}_{latitude}_{longitude}_{start}-{end}_CERES.txt" > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ^ > SyntaxError: invalid syntax > > My suspicion is that I might be using an outdated version, since I dimly > remember having to update python before I ran the script back in April. > But then I don't understand why the python I'm now calling has suddenly > gone back to an earlier version, i.e., Python 2.7.? Since I'm very > unfamiliar with python syntax, I thought I'd best ask someone who knows > python what the problem really and how I can fix it. You are exactly right: F-strings only arrived in Python with v3.6. Open a terminal and at the command-line type "python". Version information is normally output, eg dn $ ... python Python 3.11.3 (main, May 24 2023, 00:00:00) [GCC 12.3.1 20230508 (Red Hat 12.3.1-1)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> (the quit-command is: exit() NB the commands to start Python vary according to OpSys (and maybe even how it was installed. Given that you are talking of Python 2, please try a command such as: python3 or py3 and see if that starts a different Python interpreter... If it is not possible/easy/sensible to update the Python interpreter currently running on your machine, The may be alternative to installing it in 'user-space' (cf part of the OpSys) or perhaps to set it up in a virtual-machine or "container". > The complete code is attached along with a sample input file with 7 > locations.? If anyone's curious what this code is supposed to do, it > retrieves synthetic weather data for any location on earth just by > giving the latitude, longitude, and time period. Coincidentally, was just designing an assignment in the behavior of (Python) objects today, which involves correctly handling lat-long location-data... > I see two possible options to solve this problem:? (1) if it is a > problem due to the python version,? I would need to find what happened > to my Python 3.X ?? (2) if it's a generic syntax error, please tell me > what that line should be? I can't believe that down-grading existing code to Python 2 is a sensible idea. For example, every single print() call (Python 3) would have to be changed into a Python 2 print-statement. Plus, only for the short period until your son returns... -- Regards, =dn From alan.gauld at yahoo.co.uk Mon Jun 26 08:07:15 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 26 Jun 2023 13:07:15 +0100 Subject: [Tutor] Need help in understanding why I'm now getting a SyntaxError on a previously working code In-Reply-To: References: Message-ID: On 26/06/2023 05:58, Joe Huang wrote: > ? File "wkg_API_points.py", line 33 > ??? filename = f"{locname}_{latitude}_{longitude}_{start}-{end}_CERES.txt" > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ^ > SyntaxError: invalid syntax > > My suspicion is that I might be using an outdated version, That would explain it since format strings are a quite recent introduction. But there are many, many, minor changes in syntax etc between python 3 and 2. Also Python 2 is now officially obsolete and unsupported. So the first step is definitely to upgrade to, say, v3.10 or higher -- 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 simpsonrmz41 at gmail.com Mon Jun 26 06:16:17 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Mon, 26 Jun 2023 20:16:17 +1000 Subject: [Tutor] Testing functions Message-ID: Hi. I have just been playing around with functions and wanted to know where should i be in putting variables to test out a function block i have written? This one is just an example for demonstration but where should I be defining the value of username here to test the function? >>> def hint_username(username): ... if len(username) < 3: ... print("Invalid username, must be at least 3 characters long") ... else: .. . print("Valid username") From simpsonrmz41 at gmail.com Mon Jun 26 07:11:26 2023 From: simpsonrmz41 at gmail.com (Jack Simpson) Date: Mon, 26 Jun 2023 21:11:26 +1000 Subject: [Tutor] Inputting variables into functions containing if, elif, else. Message-ID: Hi, I was hoping to gain some knowledge on how I can test out a function. Should I have used the return function somewhere or have I totally missed a step? Or have I not defined a variable properly? number = 25 if number <= 5: print("The number is 5 or smaller.") elif number == 33: print("The number is 33.") elif number < 32 and number >= 6: print("The number is less than 32 and greater than 6.") else: print("The number is " + str(number)) From PythonList at DancesWithMice.info Mon Jun 26 08:53:48 2023 From: PythonList at DancesWithMice.info (dn) Date: Tue, 27 Jun 2023 00:53:48 +1200 Subject: [Tutor] Testing functions In-Reply-To: References: Message-ID: <6534641d-5f6a-b32e-807e-34d1279403a8@DancesWithMice.info> On 26/06/2023 22.16, Jack Simpson wrote: > Hi. > I have just been playing around with functions and wanted to know where > should i be in putting variables to test out a function block i have > written? > > This one is just an example for demonstration but where should I be > defining the value of username here to test the function? > >>>> def hint_username(username): > ... if len(username) < 3: > ... print("Invalid username, must be at least 3 characters > long") > ... else: > .. . print("Valid username") In the function-call, eg hint_username( "Fred" ) Same as you would for len( string_identifier ) Isn't this covered in previous exchange? (or have I misunderstood the question?) -- Regards, =dn From threesomequarks at proton.me Mon Jun 26 10:54:35 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Mon, 26 Jun 2023 14:54:35 +0000 Subject: [Tutor] Inputting variables into functions containing if, elif, else. In-Reply-To: References: Message-ID: Jack, Maybe you can explain things better. I assume the phrase "test out" means you want to try various test cases to see if a function operates as expected under various inputs. So where is your function? You are not showing a function but snippets of code that could be embedded in a function. If you want to test the code the way you have it, then when asking us, don't call it a FUNCTION, please. If you just want to test your logic, then you can keep changing the current value of "number" and run the remaining lines and see what pops out. If you had an actual function such as do_it(numb) that you can call it repeatedy, you could call do_it(0) then do_it(666) and do_it("This is not a number") and so on. And there are ways to automate the process by automatically calling the function in multiple ways and comparing it to the expected result and perhaps just reporting how many tests passed or failed but those are outside what you seem to be working on. Can I ask you about the code you showed and whether it is organized the way you want? It looks like you are expecting a number and want to partition it into 4 categories. The first is less than or equal to 5 which I note includes possibly negative numbers. Are they definitely integers? Do you care about 0 or negative numbers? The second jumps to test for exactly 33. Nothing wrong with that but not the order of testing I might have chosen. The third jumps back to test is the number is at least six but strictly less than 32. I suggest you ask yourself what if it is exactly 32. And look at your print statement and note is does NOT say what the code does. it says GREATER than 6 while the code says >= 6. The final condition catches anything not caught by the others. It looks to me like it would find not only any number greater than 33 but also any 32 and for that matter any floating point numbers between 32 and 33 such as 32.5. There is no one way to write most code. What some people might do is strive for efficiency by making the most commonly expected test cases go first so the remaining IF statements rarely get evaluated. Others may use some logical progression like this, assuming you have an integer and there are no gaps allowed: number <= 5 number <= 32 number == 33 else ... Sent with Proton Mail secure email. ------- Original Message ------- On Monday, June 26th, 2023 at 7:11 AM, Jack Simpson wrote: > Hi, > > I was hoping to gain some knowledge on how I can test out a function. > Should I have used the return function somewhere or have I totally missed a > step? > Or have I not defined a variable properly? > > number = 25 > > > if number <= 5: > print("The number is 5 or smaller.") > elif number == 33: > print("The number is 33.") > elif number < 32 and number >= 6: > > print("The number is less than 32 and greater than 6.") > else: > print("The number is " + str(number)) > _______________________________________________ > 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 Mon Jun 26 14:20:08 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 26 Jun 2023 19:20:08 +0100 Subject: [Tutor] Inputting variables into functions containing if, elif, else. In-Reply-To: References: Message-ID: On 26/06/2023 12:11, Jack Simpson wrote: > Hi, > > I was hoping to gain some knowledge on how I can test out a function. > Should I have used the return function somewhere or have I totally missed a > step? You have missed a vital step. You haven't created a function. I think you might still be misssing a concept here. A function is like a little mini-program that has its own name. You can then call that mini-program from inside your own programs. You create such a mini-program using the def keyword def mini_program(input values here): > Or have I not defined a variable properly? > > number = 25 You have defined the variable number and given it the value 25. But... > if number <= 5: > print("The number is 5 or smaller.") > elif number == 33: > print("The number is 33.") > elif number < 32 and number >= 6: > print("The number is less than 32 and greater than 6.") > else: > print("The number is " + str(number)) This is just regular code. It is not inside a function. To do that you need to put all of the above code underneath a def statement. Like this(note the all-important indentation!): def test_number(aNumber): if aNumber <= 5: print("The number is 5 or smaller.") elif Anumber == 33: print("The number is 33.") elif aNnumber < 32 and aNumber >= 6: print("The number is less than 32 and greater than 6.") else: print("The number is " + str(number)) And then you can call it with your number variable from above: test_number(number) A couple of bonus points: The line elif aNnumber < 32 and aNumber >= 6: can be written: elif 6 =< aNumber < 32: It doesn't make much difference but saves a little typing. Just be careful about which comparison sign you use. Also, the line print("The number is " + str(number)) can be written print("The number is ",number) print() will automatically convert things to strings if possible. And doing it this way is actually very slightly faster and memory efficient than adding the two strings together. -- 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 Mon Jun 26 16:17:32 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 26 Jun 2023 14:17:32 -0600 Subject: [Tutor] Testing functions In-Reply-To: References: Message-ID: <30fe03f0-2878-276a-05a8-3fb4edb994e2@wichmann.us> On 6/26/23 04:16, Jack Simpson wrote: > Hi. > I have just been playing around with functions and wanted to know where > should i be in putting variables to test out a function block i have > written? > > This one is just an example for demonstration but where should I be > defining the value of username here to test the function? > >>>> def hint_username(username): > ... if len(username) < 3: > ... print("Invalid username, must be at least 3 characters long") > ... else: > .. . print("Valid username") Here's one possibility: You can write test functions that hold the various combinations you want to try. If you use an existing test framework this is pretty simple. You can prepare a test function that has the same name but a "test_" prefix, and write the tests to validate your usage there. The great thing about writing tests this way - "together with your code" - is you often think of cases that you didn't think of originally when writing your function - there's even a line of thinking that you should write your tests first, then write the code so the tests pass. Anyway - what if someone misunderstands and passes an integer to your function. What should it do? So here's a really trivial example using a variant of your code (notice the "print" calls have been replaced with a return - it's more common to have a function "do something" rather than print stuff - the latter is kind of typical when you're just starting out but becomes less prominent later). The test framework handles running the tests for you. def hint_username(username): if len(username) < 3: return "Invalid username, must be at least 3 characters long" else: return "Valid username" def test_hint_username(): # are short names detected? assert hint_username("gb") == "Invalid username, must be at least 3 characters long" # are long names accepted? assert hint_username("georgebrown") == "Valid username" # are bogus usernames rejected? # assert hint_username(123) == ?? what should function return here? PyTest will perform "test discovery" - files whose names start with test_ if you give it no filenames to search, and locate what look like test functions in those, or if you give it filenames, it will look for test functions in those (starting wtih test_), and run them for you. Like: $ pytest username.py ============================= test session starts ============================== platform linux -- Python 3.11.3, pytest-7.3.2, pluggy-1.2.0 rootdir: /home/user/work plugins: typeguard-4.0.0 collected 1 item username.py . [100%] ============================== 1 passed in 0.00s =============================== $ From threesomequarks at proton.me Mon Jun 26 20:34:54 2023 From: threesomequarks at proton.me (ThreeBlindQuarks) Date: Tue, 27 Jun 2023 00:34:54 +0000 Subject: [Tutor] Testing functions In-Reply-To: <30fe03f0-2878-276a-05a8-3fb4edb994e2@wichmann.us> References: <30fe03f0-2878-276a-05a8-3fb4edb994e2@wichmann.us> Message-ID: Matt gave a somewhat more advanced reply as to how to test the function you want which might look a bit more like this: So here is a variation of your code where there is a function called "categorize" that does not print anything but just returns a default string or a specific one: def categorize(number): value = "The number is " + str(number) if number <= 5: value = "The number is 5 or smaller." elif number == 33: value = "The number is 33." elif number < 32 and number >= 6: value = "The number is less than 32 and greater than 6." return value You can test it by hand at the prompt: >>> categorize(1) 'The number is 5 or smaller.' >>> categorize(666) 'The number is 666' >>> categorize(32.5) 'The number is 32.5' Or you can use a loop to test say from -2 to 35-1 as in: for numberness in range(-2,35): print(numberness, ": ", categorize(numberness)) You get something like this: -2 : The number is 5 or smaller. -1 : The number is 5 or smaller. 0 : The number is 5 or smaller. 1 : The number is 5 or smaller. 2 : The number is 5 or smaller. 3 : The number is 5 or smaller. 4 : The number is 5 or smaller. 5 : The number is 5 or smaller. 6 : The number is less than 32 and greater than 6. 7 : The number is less than 32 and greater than 6. 8 : The number is less than 32 and greater than 6. 9 : The number is less than 32 and greater than 6. 10 : The number is less than 32 and greater than 6. 11 : The number is less than 32 and greater than 6. 12 : The number is less than 32 and greater than 6. 13 : The number is less than 32 and greater than 6. 14 : The number is less than 32 and greater than 6. 15 : The number is less than 32 and greater than 6. 16 : The number is less than 32 and greater than 6. 17 : The number is less than 32 and greater than 6. 18 : The number is less than 32 and greater than 6. 19 : The number is less than 32 and greater than 6. 20 : The number is less than 32 and greater than 6. 21 : The number is less than 32 and greater than 6. 22 : The number is less than 32 and greater than 6. 23 : The number is less than 32 and greater than 6. 24 : The number is less than 32 and greater than 6. 25 : The number is less than 32 and greater than 6. 26 : The number is less than 32 and greater than 6. 27 : The number is less than 32 and greater than 6. 28 : The number is less than 32 and greater than 6. 29 : The number is less than 32 and greater than 6. 30 : The number is less than 32 and greater than 6. 31 : The number is less than 32 and greater than 6. 32 : The number is 32 33 : The number is 33. 34 : The number is 34 Now obviously you would need to inspect the above by hand to see if it makes sense. And there are many ways to test selected ranges. And you might supplement it with explorations like this: >>> categorize() TypeError: categorize() missing 1 required positional argument: 'number' >>> categorize(5, 32) TypeError: categorize() takes 1 positional argument but 2 were given >>> categorize("42") TypeError: '<=' not supported between instances of 'str' and 'int' >>> categorize(complex(3, 5)) TypeError: '<=' not supported between instances of 'complex' and 'int' Obviously some of these tests might be deemed irrelevant but they might actually make you reconsider and rewrite things. Of course if the requirements for the project are only what is described, you can stop here, As an example, you could have the code not FAIL when given cases like the above. You could define the function to take anything from no arguments to a lot of arguments and then check what you got and do something appropriate. For no arguments, the return would be that the category is NOTHING. For multiple, maybe you return a list of individual categories. Maybe if you got a string as an argument, you might try to convert it to an "int" and if it works, categorize it. If it is imaginary, maybe test the real part. Floating point numbers maybe can be rounded or truncated. You get the idea. Note again my example function is not quite the same as your code and is designed to return a string rather than print it. And for more significant testing, as several have mentioned, there are MANY options that help automate it. And as I noted earlier, your code does not seem quite correct to me. -Q Sent with Proton Mail secure email. ------- Original Message ------- On Monday, June 26th, 2023 at 4:17 PM, Mats Wichmann wrote: > On 6/26/23 04:16, Jack Simpson wrote: > > > Hi. > > I have just been playing around with functions and wanted to know where > > should i be in putting variables to test out a function block i have > > written? > > > > This one is just an example for demonstration but where should I be > > defining the value of username here to test the function? > > > > > > > def hint_username(username): > > > > > ... if len(username) < 3: > > > > > ... print("Invalid username, must be at least 3 characters long") > > > > > ... else: > > > > > .. . print("Valid username") > > > Here's one possibility: > > You can write test functions that hold the various combinations you want > to try. If you use an existing test framework this is pretty simple. > You can prepare a test function that has the same name but a "test_" > prefix, and write the tests to validate your usage there. The great > thing about writing tests this way - "together with your code" - is you > often think of cases that you didn't think of originally when writing > your function - there's even a line of thinking that you should write > your tests first, then write the code so the tests pass. Anyway - what > if someone misunderstands and passes an integer to your function. What > should it do? > > So here's a really trivial example using a variant of your code > (notice the "print" calls have been replaced with a return - it's more > common to have a function "do something" rather than print stuff - the > latter is kind of typical when you're just starting out but becomes less > prominent later). The test framework handles running the tests for you. > > def hint_username(username): > if len(username) < 3: > return "Invalid username, must be at least 3 characters long" > else: > return "Valid username" > > def test_hint_username(): > # are short names detected? > assert hint_username("gb") == "Invalid username, must be at least > 3 characters long" > # are long names accepted? > assert hint_username("georgebrown") == "Valid username" > # are bogus usernames rejected? > # assert hint_username(123) == ?? what should function return here? > > > PyTest will perform "test discovery" - files whose names start with > test_ if you give it no filenames to search, and locate what look like > test functions in those, or if you give it filenames, it will look for > test functions in those (starting wtih test_), and run them for you. > Like: > > $ pytest username.py > ============================= test session starts > ============================== > platform linux -- Python 3.11.3, pytest-7.3.2, pluggy-1.2.0 > rootdir: /home/user/work > plugins: typeguard-4.0.0 > collected 1 item > > username.py . > [100%] > > ============================== 1 passed in 0.00s > =============================== > $ > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From trent.shipley at gmail.com Tue Jun 27 12:46:45 2023 From: trent.shipley at gmail.com (trent shipley) Date: Tue, 27 Jun 2023 09:46:45 -0700 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: Message-ID: On Fri, Jun 23, 2023 at 5:51?PM Alan Gauld via Tutor wrote: > On 23/06/2023 18:11, trent shipley wrote: > > I have written the simple core logic for a dice rolling program. It is > In > > ./app/core. I am planning to add more complex helper classes in > > separate files to do more complex things like rolling different kinds of > > dice in one throw, or exploding dice. > > > > I plan four interfaces, two CLI, and two GUI. > > When you say "interfaces" I assume you mean user interfaces? > Or do you include an API so that other programmers can use > your code too? > > I mean four user interfaces are planned, in addition to direct access to the dice rolling logic itself as a python module or package. > If we restrict ourselves to user interfaces, did you design > your code to follow the MVC pattern? If so, it should be easy > to implement VC classes for each type of UI, and also Web > or network interfaces if needed later. > > If you didn't use an MVC architecture then you should probably > rework the core code to be a model that can speak to views and > controllers. It will make life much easier for everyone. > > If the math logic of the program is the model and the UI is the view, then I thought the role of the controller was to put a dependent abstraction between the model and the view? > > 1. A pretty simple CLI with just the basic core functionality. > > 2. A small DSL for rolling dice, with support for complexities like > > using pre-provisioned numpy probability functions and using in one > throw, > > re-rolls if a result is in a certain range and so on. > > 3. A GUI meeting common requirements for role-playing games. > > 4. A "Scientific GUI" with some, but not all, of the power of the > > command line and scriptable DSL. > > That is a combination of vague waffle and domain specific gobbledegook. > We can't possibly guess what that means. > > > *Buried Lead:* > > I am now working on #1 the Simple CLI. ** How do I arrange things so I > can > > run ./app/cli/simple_cli/simple_hdroll_cli_main.py as "$ > > python3 shdroll kwargs"? ** > > Create an alias on your OS? > That might work. I think I'll just rename the source code file I want to run to 'shdroll'. > > > Looking to the future, how do I package and distribute my project so it > can > > be used conveniently on all three OSes per my design intent. > > Which three OS? There are many more than 3 OS in the world. > Which OS do you have in mind? > I was thinking of the program as running on consumer 'desktop' OSes, so Windows, Mac, and some Linux families which are popular for desktop use, but not Chrome. The design is really vulnerable to injection attacks, so providing a web interface "might not be a good idea". As for Android and iOS, I'm not even thinking of that now. > > I'll take a guess at Windows and MacOS Cocoa as two? > The third could be web(and thee are several options there?!), > CLI, Posix, Unix/CDE, Linux(which desktop>?), MVS, VMS, etc, etc. > > (The command > > line interfaces work like command line commands, The DSL can interpret > and > > run scripts, and the GUIs act like native GUI programs for all three > OSes. > > (I am developing on Linux Mint.)) > > Even stating Linux Mint still leaves us guessing over desktop > - Cinnamon, Mate, LXDE, etc? > Cinnamon. > > User interfaces are very specific things. You can't even just say > GUI. There are many GUI frameworks and they are all quite different. > Are you using Tkinter, wxPython, pyGTK, Side, or the native toolkits > for each OS - Windows MFC(via pythonwin) or the .NET framework - > possibly via IronPython?! Or Cocoa on MacOS? > Or Java Swing using jython - that would be cross OS, and work on > much more than 3 OS. > > > I have not gotten as far as selecting a Python friendly GUI framework. I used tkInter once in a 100 level class. I'd like to stay with an 'all Python' design so that the package is "easy" for other Python programmers to modify. > -- > 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 trent.shipley at gmail.com Tue Jun 27 16:35:13 2023 From: trent.shipley at gmail.com (trent shipley) Date: Tue, 27 Jun 2023 13:35:13 -0700 Subject: [Tutor] ModuleNotFoundError in Terminal, PyCharm OK Message-ID: PyCharm can run the code below or process the marked line, #2, in the console, as in the snip, below, but I can't figure out how to feed the program command line args. import simple_hdroll_cli_parser as shdroll_cli from app.core import core_dice_roller as core ## problem here parse_cli_args = shdroll_cli.SimpleHDRollCliParser() kwargs = parse_cli_args.parse() if kwargs.add is not None: transform = core.add_currying(kwargs.add) elif kwargs.mult is not None: transform = core.multiply_currying(kwargs.mult) else: transform = None # Create a die die = core.IntegerDie(transform_fn=transform, sides=kwargs.sides, bottom=kwargs.base) ### continues ### No main ### END ### A terminal on Mint Cinnamon reliably does this: (venv) trent at trent-virtual-machine:~/pythonworkspace/hackable_dice_roller/app/cli/simple_cli$ python3 shdroll.py Traceback (most recent call last): File "/home/trent/pythonworkspace/hackable_dice_roller/app/cli/simple_cli/shdroll.py", line 2, in from app.core import core_dice_roller as core ModuleNotFoundError: No module named 'app' Google has many answers for PyCharm can't find my module, but the command line can, but none for the other way around. And the files: . ??? app ? ??? cli ? ? ??? __init__.py ? ? ??? __pycache__ ? ? ??? simple_cli ? ? ??? __init__.py ? ? ??? __pycache__ ? ? ??? shdroll.py ? ? ??? simple_hdroll_cli_parser.py ? ??? core ? ? ??? core_dice_roller.py ? ? ??? __init__.py ? ? ??? __pycache__ ? ??? gui ? ? ??? __init__.py ? ? ??? simple_gui ? ? ??? __init_.py ? ??? __init__.py ? ??? __pycache__ ? ??? tests ? ??? cli ? ? ??? __init__.py ? ? ??? simple_cli ? ? ??? __init__.py ? ??? core ? ? ??? __init__.py ? ? ??? __pycache__ ? ? ??? test_hdr_core.py ? ? ??? test_hdr_core_visually.py ? ??? gui ? ??? __init__.py ? ??? simple_gui ? ??? __init__.py ??? __init__.py ??? README 17 directories, 18 files From alan.gauld at yahoo.co.uk Tue Jun 27 17:16:03 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 27 Jun 2023 22:16:03 +0100 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: Message-ID: On 27/06/2023 17:46, trent shipley wrote: > If the math logic of the program is the model and the UI is the view, then > I thought the role of the controller was to put a dependent abstraction > between the model and the view? One of the problems with MVC is that there are now many variants so anything I say can be contradicted in some specific implementation. However, in classic MVC(as per Smalltalk80) the model is the set of objects implementing the core logic and data. The views(multiple) represent the visual UI which presents the model to the user. The controller interacts with the user by receiving input events and converting them into messages to the model or view as appropriate. [Some designers favour a single controller for each "principal screen or dialog", others like to have one per use-case. I'm in the former camp but I've seen both approaches work.) So, when you press a button on a view the button press is received by the controller. That then decides if the button action requires the model to do something(fetch new data, perform calculations etc) or whether it's merely a view update(reordering a list for example). If the model is chosen the model will perform the action then broadcast an update to all of its registered views(*) so that they can update the display if necessary. (*)Some MVC implementations make the controller the "view register" so that the model only has to talk to the controller, which knows which views are interested in which model objects. One of the areas of divergence in different MVC implementations. In either case the idea is that when a view is instantiated it registers itself against the relevant models. The framework must ensure that when a model changes all associated views are notified of the change. > I was thinking of the program as running on consumer 'desktop' OSes, so > Windows, Mac, and some Linux families which are popular for desktop use, > but not Chrome. The design is really vulnerable to injection attacks, Injection attacks are possible on any OS but certainly the web is much more of a risk. If you use a cross platform GUI toolkit then packaging should be pretty straightforward in terms of creating the app files etc. Creating an installer to put the files where you want them and so forth is much more tricky and will require OS specific solutions. To be honest its so long since I deployed a desktop GUI for more than some personal friends/colleagues that I can't be specific. I'm pretty sure my experience(late 90s early 00s!) will be out of date nowadays! Hopefully, someone else on the list will have experience to share. Failing that I'd try the user fora for whichever GUI toolkit you choose. >> I have not gotten as far as selecting a Python friendly GUI framework. I > used tkInter once in a 100 level class. I'd like to stay with an 'all > Python' design so that the package is "easy" for other Python programmers > to modify. Tkinter is best for Python friendliness but has least functionality and is least pretty(even using the new ttk widgets). wxPython looks much better and is fairly easy to pick up. pyQt/Side is most powerful but also the biggest learning curve. Qt also had some licensing issues which I think have been solved(especially if using Side) but i don;t know the details - I'm not a Qt user. -- 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 PythonList at DancesWithMice.info Tue Jun 27 18:12:56 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 28 Jun 2023 10:12:56 +1200 Subject: [Tutor] ModuleNotFoundError in Terminal, PyCharm OK In-Reply-To: References: Message-ID: On 28/06/2023 08.35, trent shipley wrote: > PyCharm can run the code below or process the marked line, #2, in the > console, as in the snip, below, but I can't figure out how to feed the > program command line args. Recommend a review of the way Python keeps track of various and multiple directories, and thus how/where it finds the modules for import-ing: https://docs.python.org/3/using/cmdline.html Thereafter, add debug code/create snippet to display the PYTHONPATH, and run from (same dir as this) in both PyCharm and terminal. Illumination will follow! -- Regards, =dn From mats at wichmann.us Tue Jun 27 19:40:22 2023 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 27 Jun 2023 17:40:22 -0600 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: Message-ID: <18242edf-5234-b1f4-2e9d-483121a0c3eb@wichmann.us> On 6/27/23 15:16, Alan Gauld via Tutor wrote: > Hopefully, someone else on the list will have experience to share. > Failing that I'd try the user fora for whichever GUI toolkit you > choose. One of them even has documentation: https://doc.qt.io/qtforpython-6/overviews/model-view-programming.html From PythonList at DancesWithMice.info Wed Jun 28 00:58:46 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 28 Jun 2023 16:58:46 +1200 Subject: [Tutor] Multiple front-ends in project In-Reply-To: References: <3dfb4f8f-81f1-d6e4-4a1b-451d7cf4ce84@DancesWithMice.info> Message-ID: <51833c53-78f9-a5a5-7977-70e2d22f4e18@DancesWithMice.info> On 28/06/2023 05.04, trent shipley wrote: > Middle posting Responses interposed (posh talk!) > On Sun, Jun 25, 2023 at 5:34?PM dn via Tutor > wrote: > > On 24/06/2023 12.50, Alan Gauld via Tutor wrote: > > On 23/06/2023 18:11, trent shipley wrote: > >> I have written the simple core logic for a dice rolling > program.? It is In > >> ./app/core.? I am planning to add more complex helper classes in > >> separate files to do more complex things like rolling different > kinds of > >> dice in one throw, or exploding dice. > >> > >> I plan four interfaces, two CLI, and two GUI. > > Further to @Alan's analysis, (although not being aware of your level of > ComSc/DataSc expertise) I regularly remind/put the 'circles' diagram in > front of trainees > (https://blog.cleancoder.com/uncle-bob/images/2012-08-13-the-clean-architecture/CleanArchitecture.jpg ) > > > The diagram was very useful, especially the little diagram in the lower > right corner. When looking at the code, does EVERY class and function fit (only) into one of those 'circles'? The same question is probably applicable to each fitting into either one of the two CLI or one of the two GUI 'front-ends' OR is part of the actual dice-simulation 'core code'? If not, recommend some refactoring... > This illustrates that the code fulfilling the purposes of the outer > 'circles' needs to know (a limited amount of) what's going-on 'inside', > but the inner-circle(s) don't need to know where data is coming-from or > going-to! (paralleling @Alan's "MVC" ideas of 'separation') > > > I have an unfortunate habit of designing bottom-up despite having been > taught to favor doing it the other way around. No! Bottom-up can't be "design". One can't draw a jig-saw puzzle's picture by painting on successive pieces before they are assembled into the whole! In this case, you can identify your four front-ends, and a computational-core. Thereafter you could ignore all of those components except the last, and design that in more detail - only coming back to designing the others after implementation of the core. (but that's not "bottom-up") You can break-down the details of the core, 'layer by layer', each more precise than the other, until you're ready to code - and can imagine how all of that (piece of the) code will fit together. Coding can then be a bottom-up process: - a function to roll a single, six-sided (traditional) die - expand to roll the die multiple times - enhance to a variable number of 'sides' - upgrade to consider multiple dice ... That is an iterative process. Even better if, each time, you can add controlling functions which fit around the basic process! If you can keep the code modular (which in Python usually means classes and functions - with modules, perhaps when start adding the four front-ends into the picture) this will make iteration easier. Also, testing as you go solves the problem of 'where did that error actually arise' (cf where it became manifest). OK, I suspect that this was a project which started-out as a topic for learning (some) Python. In which case, 'design' was not front-of-mind, and something, perhaps the random library, was the focus of attention. No criticism! There comes a time though, when the aggregation of various ideas, inspirations, desires, imaginings, and experiments (bottom-up) starts to smell like 'warts have been grafted onto the back-side of carbuncles'. In which case, starting with a fresh sheet of paper/wiped whiteboard, and re-imagining a solution is likely the best path forward*. By this stage, one's Python knowledge has increased, and one's domain-expertise has grown. Consequently a 'design' is now possible (if not, necessary) whereas it was not before - or not the primary mission earlier. Either way, the design becomes a top-down view, starting with (perhaps) a single sentence, and becoming more and more detailed as the 'layers' become more precise. * which is not to say that you won't re-use chunks of code! Accordingly, I start with 'design' and follow the principle of stepwise decomposition. However, once coding starts, I work function-by-function, class-by-class (module-by-module!) and testing each unit as I go. I know which unit to start with, and which to code 'next' (and so-on) because 'the design' acts as a road-map. That process however, is very much bottom-up. Sometimes, when working at the code-face, it can be difficult to keep in-mind how this 'unit' plugs into the application as a whole. This is where 'design' helps one stay on the straight-and-narrow! Another aspect of 'design' (and bringing-up YAGNI/reining-in our native-enthusiasm) is that if one starts with an "MVP", then it helps us to follow the maxim "make it work before you make it 'better'!". To borrow from Fred Brooks (Architect of IBM's System/360 project), constraints can be our friends! Are you getting the feeling that no 'one size' will fit all? > If interested, please see-also theories such as "Separation of > Concerns" > and the "SOLID Principles", specifically the "Single Responsibility > Principle". In short, if the description of the work performed by a > single unit of code (eg function, class, ...) features the word "and", > then that code may contain a 'gotcha' for exercises such as this! > > > Accordingly, the code which actually includes a call to the > random-library does not need to know if the request has come from a > user > using a GUI or the CLI. Yes, other 'outer' logic can take care of > that - > and ensure that a request from the GUI will return the results in > similar fashion rather than printing to the 'command-line'. > > Considering the 'center' in a bit more detail: what data does the 'core > logic' require from its "External Interface" (regardless of which one)? > > This may include: > - how many sides to the die/dice > - how many dice > - home many rolls > ... > > Indeed. > > This is the "API" (Application Programming Interface). More > prosaically, > it is probably the 'signature' of one of the existing functions in the > system. (which is another way of getting rid of the high-falutin > terminology) > > > Yes the dice rolling logic is accessible and is what middle layers would > access. > > Once you've identified ("finalised") this, then turn your attention to > the GUI and CLI components. The 'input' part of these must be built to > be as pretty and/or as workable as is appropriate, but ultimately must > provide the information required by the (above) API/signature. > > > Is it OK to work on this iteratively, rather than trying to pin down the > needed 'business' logic and functions in one go? Sure, but... If the business-logic is updated 'internally' - for example swapping one PRNG for another, then no-problem. If you implement (say) a routine which deals with six-sided dice, and then build the four 'front-ends', everything will be fine-and-dandy. However, if you now enable multi-sided dice, not only does the 'business logic' have to be updated, but so too must each of the front-ends. Thus, the cost of change is much higher. However, you have an MVP up-and-running. Now, if you factor-in the idea that until users can actually see 'something' (today marketing-folk use the word "experience") they won't know that they want something different, bigger, brighter, better, faster, in pink, with racing-stripes, ... Once again, I'll preach the principles of 'design', of modular programming, and "structured programming". If your solution has been built with 'change' in-mind - which is somewhat similar to building-in every little option, except that you don't actually, you only build what is there, with the idea that extensions may/will come at some future stage. Flexibility... Open-Closed Principle... > The same, in-reverse, for output... > > > Referring back to the diagram. The die/dice is an "entity". The number > of sides per die is a "business rule" (the 'business' (ahem) of > statistical distribution). The "Use Cases" are the varieties of > simulations you'd like the dice to be used to perform. The > Web/UI/External Interfaces encompass many of your existing > explanations/intent. > > > Have enjoyed considering the question. Some additional comment (FWIW): > > Further to @Alan's "waffle", may I recommend the "YAGNI Principle", ie > don't 'put stuff in' until you actually receive a solid use-case for it > (in my case: I don't do things until the client has agreed to pay for > them). Just because it might be useful - or might be fun to code-up, is > not a solid reason (it *is* a reason (professional responsibility?) to > go back to the client and ask if (s)he agrees - *and* is prepared to > pay > for it!). Most of the time it represents a delay to 'delivery' because > You/They Ain't Going To Need It! > > When I build software at work, I have a horrible problem with gold > plating,?so KISS and YAGNI are real issues for?me.? The killer app I > imagined was a dice roller for RPGs with a GUI front end I could > actually use and tinker with.? The CLI version I'm working on now may > not have too much utility, And the 'advanced' or 'scientific' versions > are solutions looking for consumers. Professionalism includes discipline! Isn't dice-rolling a fairly standard intro-to-writing-code in stats courses? (was in mine - coins and dice illustrating random processes, counting, distributions, ... > Am also anticipating you will have to put in some 'rework'. Recommend > that you start with (unless you have them already) a set of tests (a > 'testing framework'). This will 'prove' (in the logic/mathematical > sense) that the existing code works correctly. This is a 'stable > state'. > Now, when something is 'reworked' in order to separate the components > and create the API (between External Interfaces and the Entities and > Use > Cases/Controllers), the tests will continue to pass - or will fail and > thereby show that the 'new work' has introduced an error (which, one > way > or the other) will need 'fixing'! It seems like more (even, > unnecessary) > work up-front, but may pay greater dividends over time... > > There are some tests.? They pass.? I don't trust them.? I've been an > SDET for functional testing of web and Windows GUIs, but have only very > recently needed to work with unit and parameter tests. Here's another personal bias: TDD - and make sure the tests are worthwhile (what point otherwise?) A potential client called for help today with a data-capture and Python problem - "it has suddenly stopped working/crashed". One of my early questions was 'what tests do you have?'. You can guess that answer... (see also conversation 'here' about using modules to better locate/isolate steps in the application, and thus locate the sources of errors) The 'good news' about unit-testing Python code is that you can use (straight-line code) Python, eg pytest. Compared with GUIs where one might have to also learn and use Selenium, or similar! > Yesterday was Scala day, today is Python day. > > Looking forward to hearing how the project progresses... -- Regards, =dn From alan.gauld at yahoo.co.uk Wed Jun 28 03:57:34 2023 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 28 Jun 2023 08:57:34 +0100 Subject: [Tutor] Multiple front-ends in project In-Reply-To: <18242edf-5234-b1f4-2e9d-483121a0c3eb@wichmann.us> References: <18242edf-5234-b1f4-2e9d-483121a0c3eb@wichmann.us> Message-ID: On 28/06/2023 00:40, Mats Wichmann wrote: > On 6/27/23 15:16, Alan Gauld via Tutor wrote: > >> Hopefully, someone else on the list will have experience to share. >> Failing that I'd try the user fora for whichever GUI toolkit you >> choose. > > One of them even has documentation: > > https://doc.qt.io/qtforpython-6/overviews/model-view-programming.html While that's useful I was actually talking about the installation deployment aspect. It used to be that you could create a Windows Installer for example that would deploy the application. And you had to provide a help file in Windows Help format etc. But I don't even know if windows still uses those anymore? I know they changed the format (to XML?) -- 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 trent.shipley at gmail.com Wed Jun 28 16:53:27 2023 From: trent.shipley at gmail.com (trent shipley) Date: Wed, 28 Jun 2023 13:53:27 -0700 Subject: [Tutor] ModuleNotFoundError in Terminal, PyCharm OK In-Reply-To: References: Message-ID: Hi dn, #1 was not very useful, but #5 https://docs.python.org/3/reference/import.html#:~:text=5.4.5.-,module.__path__,search%20for%20modules%20during%20import. was quite useful I discovered that bash had no PYTHONPATH environment variable, and that PyCharm had obligingly intelligently populated it. (And if I changed the file structure, I had to manually inform PyCharm I had changed it, even if I used the "refactor" feature.) I wound up with this: # shdroll.py import sys sys.path.extend(['../../..', # Important '../../../src', # Stuff '../../../src/core']) # Here from simple_hdroll_cli_parser import SimpleHDRollCliParser from src.core import core parse_cli_args = SimpleHDRollCliParser() kwargs = parse_cli_args.parse() if kwargs.add is not None: transform = core.add_currying(kwargs.add) elif kwargs.mult is not None: transform = core.multiply_currying(kwargs.mult) else: transform = None # not strictly necessary, but it makes my brain hurt less # Create a die die = core.IntegerDie(transform_fn=transform, sides=kwargs.sides, bottom=kwargs.base) * * * print(rolls.to_string()) ------- I also wound up with a src.py file in the ./hackable_dice_roller/src directory so it would stop complaining about a missing module in the src package. src.py has one line. from src.core import core Was that what you had in mind, or did I come up with a singularly ugly and unPythonic solution? On Tue, Jun 27, 2023 at 3:14?PM dn via Tutor wrote: > On 28/06/2023 08.35, trent shipley wrote: > > PyCharm can run the code below or process the marked line, #2, in the > > console, as in the snip, below, but I can't figure out how to feed the > > program command line args. > > Recommend a review of the way Python keeps track of various and multiple > directories, and thus how/where it finds the modules for import-ing: > https://docs.python.org/3/using/cmdline.html > > Thereafter, add debug code/create snippet to display the PYTHONPATH, and > run from (same dir as this) in both PyCharm and terminal. > > Illumination will follow! > > -- > Regards, > =dn > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From PythonList at DancesWithMice.info Wed Jun 28 17:58:42 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 29 Jun 2023 09:58:42 +1200 Subject: [Tutor] ModuleNotFoundError in Terminal, PyCharm OK In-Reply-To: References: Message-ID: <8b906754-77ca-4167-8384-3dbde839b9d0@DancesWithMice.info> On 29/06/2023 08.53, trent shipley wrote: > Hi dn, > > #1 was not very useful, but #5 > https://docs.python.org/3/reference/import.html#:~:text=5.4.5.-,module.__path__,search%20for%20modules%20during%20import. > was > quite useful > > I discovered that bash had no PYTHONPATH environment variable, and that Did you discover this by looking from BASH, or did you use Python (while it is running) to survey the paths? (Python sets it up when the interpreter starts) > PyCharm had obligingly intelligently populated it. (And if I changed the > file structure, I had to manually inform PyCharm I had changed it, even if > I used the "refactor" feature.) > > I wound up with this: > > # shdroll.py > import sys > sys.path.extend(['../../..', # Important > '../../../src', # Stuff > '../../../src/core']) # Here > from simple_hdroll_cli_parser import SimpleHDRollCliParser > from src.core import core > > parse_cli_args = SimpleHDRollCliParser() > kwargs = parse_cli_args.parse() > > if kwargs.add is not None: > transform = core.add_currying(kwargs.add) > elif kwargs.mult is not None: > transform = core.multiply_currying(kwargs.mult) > else: > transform = None # not strictly necessary, but it makes my brain hurt > less > > # Create a die > die = core.IntegerDie(transform_fn=transform, > sides=kwargs.sides, > bottom=kwargs.base) > > > * > > * > > * > > > > print(rolls.to_string()) > > ------- > > I also wound up with a src.py file in the ./hackable_dice_roller/src > directory so it would stop complaining about a missing module in the src > package. src.py has one line. > > from src.core import core > > Was that what you had in mind, or did I come up with a singularly ugly and > unPythonic solution? Yes it does seem ugly, doesn't it. However, that is a good sign. The very next sentence should be a question: "is there a better way?". Congratulations! (?) You are now ready to discuss Modules (https://docs.python.org/3/tutorial/modules.html) which will lead into "packages", and the exact scenario under discussion... NB whilst much discussion centers around mechanisms to deliver (your) libraries to A.N.Other, you can also be your own 'customer'. That said, there does seem to be many 'layers' of directories. If you suspect so, perhaps you could draw-up a chart to show how the code-units have been separated/laid-out, to aid discussion? -- Regards, =dn