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['<Control-o>']#accelerator'] = 'Ctrl+O'

 ??????? # Bind the shortcut key to the menu item
 ??????? self.mainwindow.bind('<Control-o>', 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: <a14a780c-4e30-006d-e13b-9217bdfca474@gmail.com>

This almost works correctly.

self.mainwindow.bind('<Control-o>', 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: <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>

On Thu, 1 Jun 2023 at 04:16, Phil <phillor9 at gmail.com> 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('<Control-o>', lambda event: open_menu_item.invoke()) # no error here

Hi,

Your '<Control-o>' 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 '<KeyPress-x>'

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:
  '<Control-KeyPress-o>'

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: <u5b248$4du$1@ciao.gmane.io>

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: <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com>
 <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
Message-ID: <u5b28m$4du$2@ciao.gmane.io>

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 '<KeyPress-x>'
> 
> 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:
>   '<Control-KeyPress-o>'

I have code that binds <Control-space> 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: <u5b28m$4du$2@ciao.gmane.io>
References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com>
 <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
 <u5b28m$4du$2@ciao.gmane.io>
Message-ID: <cb6d89c7-c502-fb76-7bc2-42f04741728b@DancesWithMice.info>

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 '<KeyPress-x>'
>>
>> 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:
>>    '<Control-KeyPress-o>'
> 
> I have code that binds <Control-space> 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: <cb6d89c7-c502-fb76-7bc2-42f04741728b@DancesWithMice.info>
References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com>
 <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
 <u5b28m$4du$2@ciao.gmane.io>
 <cb6d89c7-c502-fb76-7bc2-42f04741728b@DancesWithMice.info>
Message-ID: <u5ba4i$kk$1@ciao.gmane.io>

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: <u5ba4i$kk$1@ciao.gmane.io>
References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com>
 <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
 <u5b28m$4du$2@ciao.gmane.io>
 <cb6d89c7-c502-fb76-7bc2-42f04741728b@DancesWithMice.info>
 <u5ba4i$kk$1@ciao.gmane.io>
Message-ID: <e02dd8fe-2031-a603-f83b-8e982724fb3a@DancesWithMice.info>

(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: <u5b28m$4du$2@ciao.gmane.io>
References: <8a103974-6075-a53d-00cc-889439c970de@gmail.com>
 <CAMPXz=rWWOEirdp39LRZUm1xtc_MYLXZkbZH5SqBTPROqFs5zQ@mail.gmail.com>
 <u5b28m$4du$2@ciao.gmane.io>
Message-ID: <CAMPXz=qdZkWR29TYhE7OjpbxZOZ8kjw-zYC2ti=T3PB23fe1pQ@mail.gmail.com>

On Thu, 1 Jun 2023 at 21:25, Alan Gauld via Tutor <tutor at python.org> 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 '<KeyPress-x>'
> >
> > 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:
> >   '<Control-KeyPress-o>'
>
> I have code that binds <Control-space> 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('<Control-o>', ...
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: <CAEFLybK2Zs_CyJtSbomMfcokmuiS_Dn3nZ2aVowsAeskMX6yfw@mail.gmail.com>

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 <module>
    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: <CAEFLybK2Zs_CyJtSbomMfcokmuiS_Dn3nZ2aVowsAeskMX6yfw@mail.gmail.com>
References: <CAEFLybK2Zs_CyJtSbomMfcokmuiS_Dn3nZ2aVowsAeskMX6yfw@mail.gmail.com>
Message-ID: <CAKvdLD7WxNErJ05sParDr57VEqZ3XVLzOSup7rJNG01T47=H4Q@mail.gmail.com>

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 <trent.shipley at gmail.com>
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 <module>
>     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: <CAKvdLD7WxNErJ05sParDr57VEqZ3XVLzOSup7rJNG01T47=H4Q@mail.gmail.com>
References: <CAEFLybK2Zs_CyJtSbomMfcokmuiS_Dn3nZ2aVowsAeskMX6yfw@mail.gmail.com>
 <CAKvdLD7WxNErJ05sParDr57VEqZ3XVLzOSup7rJNG01T47=H4Q@mail.gmail.com>
Message-ID: <CAEFLybJusSj-j82MwzCz9osm0fSuxhzEUugN6S0S3yy8CcGAcw@mail.gmail.com>

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 <sarfraaz at gmail.com> 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 <trent.shipley at gmail.com>
> 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 <module>
>>     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: <CAEFLyb++EMbPYVqhm2jb8iqj=sxzbeHqiVu9Wa3UTxjfkDbopA@mail.gmail.com>

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: <CAEFLyb++EMbPYVqhm2jb8iqj=sxzbeHqiVu9Wa3UTxjfkDbopA@mail.gmail.com>
References: <CAEFLyb++EMbPYVqhm2jb8iqj=sxzbeHqiVu9Wa3UTxjfkDbopA@mail.gmail.com>
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: <CAEFLybJusSj-j82MwzCz9osm0fSuxhzEUugN6S0S3yy8CcGAcw@mail.gmail.com>
References: <CAEFLybK2Zs_CyJtSbomMfcokmuiS_Dn3nZ2aVowsAeskMX6yfw@mail.gmail.com>
 <CAKvdLD7WxNErJ05sParDr57VEqZ3XVLzOSup7rJNG01T47=H4Q@mail.gmail.com>
 <CAEFLybJusSj-j82MwzCz9osm0fSuxhzEUugN6S0S3yy8CcGAcw@mail.gmail.com>
Message-ID: <CAKvdLD7D0s4wQvjgdUvzTJbpKgLbk4U47Wj731d+HMxj5nrQmA@mail.gmail.com>

On Wed, Jun 7, 2023 at 11:39?PM trent shipley <trent.shipley at gmail.com>
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: <CAEFLyb++EMbPYVqhm2jb8iqj=sxzbeHqiVu9Wa3UTxjfkDbopA@mail.gmail.com>
 <7db7538f-e441-b50b-c6b7-cbf4d8f6a1e3@DancesWithMice.info>
Message-ID: <u5s0st$2i5$1@ciao.gmane.io>

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: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>

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: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>
References: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>
Message-ID: <sXvgoVOsnNdh_q3N5ynHRnC3o10mC3bLdZbS9ms75QlqFZCM1jwx0rNUGbfsK4AqdMfL5iuIb7-dLhhO1TQHbMQ6RxzTErVDJXIh63qQ_HI=@proton.me>


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

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: <sXvgoVOsnNdh_q3N5ynHRnC3o10mC3bLdZbS9ms75QlqFZCM1jwx0rNUGbfsK4AqdMfL5iuIb7-dLhhO1TQHbMQ6RxzTErVDJXIh63qQ_HI=@proton.me>
References: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>
 <sXvgoVOsnNdh_q3N5ynHRnC3o10mC3bLdZbS9ms75QlqFZCM1jwx0rNUGbfsK4AqdMfL5iuIb7-dLhhO1TQHbMQ6RxzTErVDJXIh63qQ_HI=@proton.me>
Message-ID: <UYuDIEsLNyLdUyNggpJnN9ksuUSs6v9w5fzcZxwbFVQpNrvWv9g48hHQqNiNniWLS-U2KZ1-EkzOkmjyZkmJjboMg7urVsLXFUEDq3nnz5s=@proton.me>



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 <tutor at python.org> 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: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>
References: <CAGJtH9Sttx_+ScLTJW4m==_f4Lq2tJ3t++PVpDMA2bkR2TM4iQ@mail.gmail.com>
Message-ID: <u5tqon$i0c$1@ciao.gmane.io>

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: <CACvSQBz--+fHenPwzOM1b-Tbp9aF20eNnE5x34BMs254m3=3kg@mail.gmail.com>

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: <CACvSQBz--+fHenPwzOM1b-Tbp9aF20eNnE5x34BMs254m3=3kg@mail.gmail.com>
References: <CACvSQBz--+fHenPwzOM1b-Tbp9aF20eNnE5x34BMs254m3=3kg@mail.gmail.com>
Message-ID: <c80384cf-9ffe-43ec-ed6e-9c8c9e5242ac@wichmann.us>

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: <CACvSQBz--+fHenPwzOM1b-Tbp9aF20eNnE5x34BMs254m3=3kg@mail.gmail.com>
References: <CACvSQBz--+fHenPwzOM1b-Tbp9aF20eNnE5x34BMs254m3=3kg@mail.gmail.com>
Message-ID: <u64vep$hs0$1@ciao.gmane.io>

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.

<shameless plug>
Or you could try mine :-)
(see below)
</shameless plug>


-- 
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: <CAM53q1S99_64Nmy7NS2Vb7kqSjf9qjBQRC_dQsCfNs_Dv4i2pQ@mail.gmail.com>

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: <mailman.4.1686585601.11986.tutor@python.org>
References: <mailman.4.1686585601.11986.tutor@python.org>
Message-ID: <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>

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 <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
> Today's Topics:
>
>    1. Re: Learn Python (Alan Gauld)
>    2. Re: Learn Python (Goran Ikac)
>
>
>
> ---------- Forwarded message ----------
> From: Alan Gauld <alan.gauld at yahoo.co.uk>
> 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.
>
> <shameless plug>
> Or you could try mine :-)
> (see below)
> </shameless plug>
>
>
> --
> 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 <goranikac65 at gmail.com>
> 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: <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
References: <mailman.4.1686585601.11986.tutor@python.org>
 <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
Message-ID: <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>

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: <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>
References: <mailman.4.1686585601.11986.tutor@python.org>
 <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
 <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>
Message-ID: <u6anvj$c88$1@ciao.gmane.io>

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: <u6anvj$c88$1@ciao.gmane.io>
References: <mailman.4.1686585601.11986.tutor@python.org>
 <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
 <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>
 <u6anvj$c88$1@ciao.gmane.io>
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: <u6anvj$c88$1@ciao.gmane.io>
References: <mailman.4.1686585601.11986.tutor@python.org>
 <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
 <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>
 <u6anvj$c88$1@ciao.gmane.io>
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: <mailman.4.1686585601.11986.tutor@python.org>
 <CALgefLfMkt0ZGAqi_HAyWmf_azaXNBDC3gr-gtcnjTzxZWC3_Q@mail.gmail.com>
 <ddd66058-d74f-7b7c-dd29-aa2443cd20c8@wichmann.us>
 <u6anvj$c88$1@ciao.gmane.io>
 <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 <tutor at python.org> 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: <CA+L4kqmgsGbG=J_k35yXKFdYos3pGJGxCRBUx7BK501Rn5eedA@mail.gmail.com>

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: <CA+L4kqmgsGbG=J_k35yXKFdYos3pGJGxCRBUx7BK501Rn5eedA@mail.gmail.com>
References: <CA+L4kqmgsGbG=J_k35yXKFdYos3pGJGxCRBUx7BK501Rn5eedA@mail.gmail.com>
Message-ID: <u6nlk9$10c5$1@ciao.gmane.io>

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: <CAOP=N3f_hOsYYKW36tqq9KGeozBH+6M3BwjcbyZXuXAryQ+3Nw@mail.gmail.com>

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: <CAOP=N3f_hOsYYKW36tqq9KGeozBH+6M3BwjcbyZXuXAryQ+3Nw@mail.gmail.com>
References: <CAOP=N3f_hOsYYKW36tqq9KGeozBH+6M3BwjcbyZXuXAryQ+3Nw@mail.gmail.com>
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: <CAOP=N3fau+UiOnuoeWFoZzFhNdCTcGhXDCKozUA+Z7KQgXRkzg@mail.gmail.com>
References: <CAOP=N3f_hOsYYKW36tqq9KGeozBH+6M3BwjcbyZXuXAryQ+3Nw@mail.gmail.com>
 <62d103b1-64d9-9e12-a350-50eab8ce47cf@DancesWithMice.info>
 <CAOP=N3fau+UiOnuoeWFoZzFhNdCTcGhXDCKozUA+Z7KQgXRkzg@mail.gmail.com>
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: <mailman.4.1687190401.30660.tutor@python.org>
References: <mailman.4.1687190401.30660.tutor@python.org>
Message-ID: <CAO5j+JB2Vgzv3BefyjE2Ls2wpSsEsxH3WhruYNyNGaNQNe+fow@mail.gmail.com>

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, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
> Today's Topics:
>
>    1. Question (Katherine Gillig)
>    2. Re: Question (Alan Gauld)
>
>
>
> ---------- Forwarded message ----------
> From: Katherine Gillig <katherinegillig7 at gmail.com>
> 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 <alan.gauld at yahoo.co.uk>
> 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: <CAO5j+JB2Vgzv3BefyjE2Ls2wpSsEsxH3WhruYNyNGaNQNe+fow@mail.gmail.com>
References: <mailman.4.1687190401.30660.tutor@python.org>
 <CAO5j+JB2Vgzv3BefyjE2Ls2wpSsEsxH3WhruYNyNGaNQNe+fow@mail.gmail.com>
Message-ID: <u6s5fn$fg1$1@ciao.gmane.io>

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: <u6s5fn$fg1$1@ciao.gmane.io>
References: <mailman.4.1687190401.30660.tutor@python.org>
 <CAO5j+JB2Vgzv3BefyjE2Ls2wpSsEsxH3WhruYNyNGaNQNe+fow@mail.gmail.com>
 <u6s5fn$fg1$1@ciao.gmane.io>
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: <CAEFLybJt-RKXGESpimO3oQ_tYXzSx8o_o9yOVxwC-oNyx50MGA@mail.gmail.com>

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: <h7279ihca3r2kervddddkvlj72lj9d67ed@4ax.com>

On Wed, 21 Jun 2023 12:25:37 -0400, Peter H Young <phyoung at comcast.net>
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, <alt><prt-sc> 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: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>

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: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
Message-ID: <u72nnf$h6j$1@ciao.gmane.io>

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:

<script type="text/vbscript">
Sub Times(N)
Dim I
For I = 1 To 12
    MsgBox I & " x " & N & " = " & I * N
Next
End Sub
</script>

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: <u72nnf$h6j$1@ciao.gmane.io>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
 <u72nnf$h6j$1@ciao.gmane.io>
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: <CAPCu4cLNQTzGhotKQ7vUi7bx+=Gc2x-Z17NUQG424M7+9i31fQ@mail.gmail.com>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
 <u72nnf$h6j$1@ciao.gmane.io>
 <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info>
 <CAPCu4cLNQTzGhotKQ7vUi7bx+=Gc2x-Z17NUQG424M7+9i31fQ@mail.gmail.com>
Message-ID: <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>

---------- Forwarded message ---------
From: Jack Simpson <simpsonrmz41 at gmail.com>
Date: Fri, 23 Jun 2023 at 1:58 pm
Subject: Re: [Tutor] Beginner struggling with python.
To: dn <PythonList at danceswithmice.info>


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 <tutor at python.org> 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: <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
 <u72nnf$h6j$1@ciao.gmane.io>
 <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info>
 <CAPCu4cLNQTzGhotKQ7vUi7bx+=Gc2x-Z17NUQG424M7+9i31fQ@mail.gmail.com>
 <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
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 <simpsonrmz41 at gmail.com>
> Date: Fri, 23 Jun 2023 at 1:58 pm
> Subject: Re: [Tutor] Beginner struggling with python.
> To: dn <PythonList at danceswithmice.info>
> 
> 
> 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 <tutor at python.org> 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: <DM5PR1301MB1996A719A7F8ED1330C6D54FDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
References: <DM5PR1301MB19960099C7D623259EC2D028DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB19962B55DB85018553FB992CDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB1996A719A7F8ED1330C6D54FDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
Message-ID: <DM5PR1301MB1996066EE5A5CEED21301D52DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>


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<http://aka.ms/weboutlook>

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: <CAEFLyb+A861o8F-eR44-L6jmXnwf5OMfoR8dWjqHLmbpTnE5fQ@mail.gmail.com>

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: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>

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: <DM5PR1301MB1996066EE5A5CEED21301D52DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
References: <DM5PR1301MB19960099C7D623259EC2D028DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB19962B55DB85018553FB992CDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB1996A719A7F8ED1330C6D54FDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB1996066EE5A5CEED21301D52DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
Message-ID: <u75cru$mn1$1@ciao.gmane.io>

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: <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
 <u72nnf$h6j$1@ciao.gmane.io>
 <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info>
 <CAPCu4cLNQTzGhotKQ7vUi7bx+=Gc2x-Z17NUQG424M7+9i31fQ@mail.gmail.com>
 <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
Message-ID: <u75d8p$mn1$2@ciao.gmane.io>

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: <CAEFLyb+A861o8F-eR44-L6jmXnwf5OMfoR8dWjqHLmbpTnE5fQ@mail.gmail.com>
References: <CAEFLyb+A861o8F-eR44-L6jmXnwf5OMfoR8dWjqHLmbpTnE5fQ@mail.gmail.com>
Message-ID: <u75dk5$mn1$3@ciao.gmane.io>

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_input.txt >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: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
Message-ID: <u75el1$ihv$1@ciao.gmane.io>

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: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>

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: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
References: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
Message-ID: <u77rdc$iv7$1@ciao.gmane.io>

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: <u77rdc$iv7$1@ciao.gmane.io>
References: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
 <u77rdc$iv7$1@ciao.gmane.io>
Message-ID: <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>

sry, I want to get 100 greatest elements (not the 100th element)

Le dim. 25 juin 2023 ? 00:42, Alan Gauld via Tutor <tutor at python.org> 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: <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>
References: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
 <u77rdc$iv7$1@ciao.gmane.io>
 <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>
Message-ID: <u781dr$ihi$1@ciao.gmane.io>

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: <u781dr$ihi$1@ciao.gmane.io>
References: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
 <u77rdc$iv7$1@ciao.gmane.io>
 <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>
 <u781dr$ihi$1@ciao.gmane.io>
Message-ID: <nH9QGRnaDAAKTXBwcdWmewu1PaEmNaSewA5QAncezNsSxqU6g_zdNEUq6aQGvR_MMmis28w-oWK2aacX9lFmDU6pPpMqtQa2hzvynD1fJmk=@proton.me>

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 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: <nH9QGRnaDAAKTXBwcdWmewu1PaEmNaSewA5QAncezNsSxqU6g_zdNEUq6aQGvR_MMmis28w-oWK2aacX9lFmDU6pPpMqtQa2hzvynD1fJmk=@proton.me>
References: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
 <u77rdc$iv7$1@ciao.gmane.io>
 <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>
 <u781dr$ihi$1@ciao.gmane.io>
 <nH9QGRnaDAAKTXBwcdWmewu1PaEmNaSewA5QAncezNsSxqU6g_zdNEUq6aQGvR_MMmis28w-oWK2aacX9lFmDU6pPpMqtQa2hzvynD1fJmk=@proton.me>
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 <threesomequarks at proton.me> 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: <CAPCu4c+vOFfE8fJDXNXTBSwB-5Hx0vrHoGUampMdtEpUo2Z-yg@mail.gmail.com>

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 "<stdin>", line 1, in <module>
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: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>

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: <CAPCu4c+vOFfE8fJDXNXTBSwB-5Hx0vrHoGUampMdtEpUo2Z-yg@mail.gmail.com>
References: <CAPCu4c+vOFfE8fJDXNXTBSwB-5Hx0vrHoGUampMdtEpUo2Z-yg@mail.gmail.com>
Message-ID: <u78rmg$dok$1@ciao.gmane.io>

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: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
References: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
Message-ID: <u78sar$14pp$1@ciao.gmane.io>

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: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
References: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
Message-ID: <B_yG7d01_Z0TY3pnXPI3NJ55XIU2OPAGTNBRMizXRb7M7mON0RIa1aBu9XXpdbqJBGVxw4BR9hsSB4EEzJ7eelIBph9E-7HvI0vL8t5btF8=@proton.me>

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 <simpsonrmz41 at gmail.com> 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: <CAGJtH9Tgnx+gwkxd0+1wfV5BRKowM53p-jMKc+KKTeKiz-5RWg@mail.gmail.com>
 <u77rdc$iv7$1@ciao.gmane.io>
 <CAGJtH9TKTja7gQki1UekjyyOz_TaAaEXqTXYF-UBeV5ETWZcZQ@mail.gmail.com>
 <u781dr$ihi$1@ciao.gmane.io>
 <nH9QGRnaDAAKTXBwcdWmewu1PaEmNaSewA5QAncezNsSxqU6g_zdNEUq6aQGvR_MMmis28w-oWK2aacX9lFmDU6pPpMqtQa2hzvynD1fJmk=@proton.me>
 <9y_xHCYpGihjwMV3PVItWaTzFKtprtTW_VWTbwN74lC3Wu_IMdPobl9bHNHLkFFyG-2MTBe-TKuH0AfB4x9r5VckUr3fUiS-fNSdlqpwu8E=@proton.me>
Message-ID: <a7f06085-35d4-503d-0b42-e109c1b53282@wichmann.us>

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: <CAPCu4c+vOFfE8fJDXNXTBSwB-5Hx0vrHoGUampMdtEpUo2Z-yg@mail.gmail.com>
References: <CAPCu4c+vOFfE8fJDXNXTBSwB-5Hx0vrHoGUampMdtEpUo2Z-yg@mail.gmail.com>
Message-ID: <fd446032-b3df-694a-9f09-9b30238bb848@DancesWithMice.info>

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 "<stdin>", line 1, in <module>
> 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: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
References: <CAPCu4cJshWCXfE5We=7e=XgJ08BB_ds+rBbdhc6=wVuUszdkKA@mail.gmail.com>
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: <DM5PR1301MB1996066EE5A5CEED21301D52DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
References: <DM5PR1301MB19960099C7D623259EC2D028DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB19962B55DB85018553FB992CDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB1996A719A7F8ED1330C6D54FDE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
 <DM5PR1301MB1996066EE5A5CEED21301D52DE23A@DM5PR1301MB1996.namprd13.prod.outlook.com>
Message-ID: <b44a3026-764e-ae35-0b4e-bd59f4c75b93@DancesWithMice.info>

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: <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
References: <CAPCu4cLN7msHv=jd71Dq_YRNZH1=i0Gj3uLU-=XKwr7yM_ERNQ@mail.gmail.com>
 <u72nnf$h6j$1@ciao.gmane.io>
 <78ecbf12-013f-76b5-c070-4ca8fcfa0fff@DancesWithMice.info>
 <CAPCu4cLNQTzGhotKQ7vUi7bx+=Gc2x-Z17NUQG424M7+9i31fQ@mail.gmail.com>
 <CAPCu4cKm4qrea7QhkjfVNc0CpGiWEJKCc2maOhNUYfA1TfdLhA@mail.gmail.com>
Message-ID: <9959be39-f0b0-8fc9-2886-53adb27c1df1@DancesWithMice.info>

On 23/06/2023 19.22, Jack Simpson wrote:
> ---------- Forwarded message ---------
> From: Jack Simpson <simpsonrmz41 at gmail.com>
> Date: Fri, 23 Jun 2023 at 1:58 pm
> Subject: Re: [Tutor] Beginner struggling with python.
> To: dn <PythonList at danceswithmice.info>
> 
> 
> 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: <u75el1$ihv$1@ciao.gmane.io>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
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: <bb870e46-4a05-f19d-a764-efe91a4ddc8b@whiteboxtechnologies.com>

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: <bb870e46-4a05-f19d-a764-efe91a4ddc8b@whiteboxtechnologies.com>
References: <bb870e46-4a05-f19d-a764-efe91a4ddc8b@whiteboxtechnologies.com>
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: <bb870e46-4a05-f19d-a764-efe91a4ddc8b@whiteboxtechnologies.com>
References: <bb870e46-4a05-f19d-a764-efe91a4ddc8b@whiteboxtechnologies.com>
Message-ID: <u7bv1j$17c6$1@ciao.gmane.io>

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: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>

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: <CAPCu4c+FKhhher9V8PASFYmMnS79+QF5XY8A3R8LTKQcGuPUDQ@mail.gmail.com>

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: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>
References: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>
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: <CAPCu4c+FKhhher9V8PASFYmMnS79+QF5XY8A3R8LTKQcGuPUDQ@mail.gmail.com>
References: <CAPCu4c+FKhhher9V8PASFYmMnS79+QF5XY8A3R8LTKQcGuPUDQ@mail.gmail.com>
Message-ID: <JbGd6OsRxMlWomP0qS6H_6lGncLokizk8qCQ3wsxJjUkFvKnk98xssftZdlJOYXizZ2yWCSFDqhsNxcQJbCThbXU5O5Ii3G2X3GyHnf0QsA=@proton.me>


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 <simpsonrmz41 at gmail.com> 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: <CAPCu4c+FKhhher9V8PASFYmMnS79+QF5XY8A3R8LTKQcGuPUDQ@mail.gmail.com>
References: <CAPCu4c+FKhhher9V8PASFYmMnS79+QF5XY8A3R8LTKQcGuPUDQ@mail.gmail.com>
Message-ID: <u7ckso$137o$1@ciao.gmane.io>

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: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>
References: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>
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: <CAPCu4cJGnfUSEkBgGOx5r4-1S-+g41rzvtTtEtJ+E_5yzExBUQ@mail.gmail.com>
 <30fe03f0-2878-276a-05a8-3fb4edb994e2@wichmann.us>
Message-ID: <Lpswfackzxn9L5eMb3Z4RQDfIgtf0NW7WGyUZXKR0Ada6Bt75IrLeKrKKc-nvGZsS9m5pnq-RMSk2mWqt2d5haidMcUbxg34ZDO5dmMkdPY=@proton.me>

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 <mats at wichmann.us> 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: <u75el1$ihv$1@ciao.gmane.io>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
Message-ID: <CAEFLyb+x71E2C7AetPsPweYG-dbKhuWWg2DGrZwufMhNCMVfZQ@mail.gmail.com>

On Fri, Jun 23, 2023 at 5:51?PM Alan Gauld via Tutor <tutor at python.org>
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: <CAEFLybKyGrxSHsBNZ517eE1NOMqLdDtvBgB1WH=hs0B9s5R3uw@mail.gmail.com>

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 <module>
    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: <CAEFLyb+x71E2C7AetPsPweYG-dbKhuWWg2DGrZwufMhNCMVfZQ@mail.gmail.com>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
 <CAEFLyb+x71E2C7AetPsPweYG-dbKhuWWg2DGrZwufMhNCMVfZQ@mail.gmail.com>
Message-ID: <u7fjik$5b2$1@ciao.gmane.io>

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: <CAEFLybKyGrxSHsBNZ517eE1NOMqLdDtvBgB1WH=hs0B9s5R3uw@mail.gmail.com>
References: <CAEFLybKyGrxSHsBNZ517eE1NOMqLdDtvBgB1WH=hs0B9s5R3uw@mail.gmail.com>
Message-ID: <a8769628-859b-9b16-0228-42a255bd059c@DancesWithMice.info>

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: <u7fjik$5b2$1@ciao.gmane.io>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
 <CAEFLyb+x71E2C7AetPsPweYG-dbKhuWWg2DGrZwufMhNCMVfZQ@mail.gmail.com>
 <u7fjik$5b2$1@ciao.gmane.io>
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: <CAEFLybJoqzXy_0vBAzh9uMVSOTqi+j+5FyAyhZLkHN-7HuFx_Q@mail.gmail.com>
References: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
 <3dfb4f8f-81f1-d6e4-4a1b-451d7cf4ce84@DancesWithMice.info>
 <CAEFLybJoqzXy_0vBAzh9uMVSOTqi+j+5FyAyhZLkHN-7HuFx_Q@mail.gmail.com>
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 <tutor at python.org 
> <mailto:tutor at python.org>> 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 <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: <CAEFLybKztxWx8bFauX0i1H_WaEpGgqUByafeUBy8P62PYoSi4A@mail.gmail.com>
 <u75el1$ihv$1@ciao.gmane.io>
 <CAEFLyb+x71E2C7AetPsPweYG-dbKhuWWg2DGrZwufMhNCMVfZQ@mail.gmail.com>
 <u7fjik$5b2$1@ciao.gmane.io>
 <18242edf-5234-b1f4-2e9d-483121a0c3eb@wichmann.us>
Message-ID: <u7gp5e$lf4$1@ciao.gmane.io>

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: <a8769628-859b-9b16-0228-42a255bd059c@DancesWithMice.info>
References: <CAEFLybKyGrxSHsBNZ517eE1NOMqLdDtvBgB1WH=hs0B9s5R3uw@mail.gmail.com>
 <a8769628-859b-9b16-0228-42a255bd059c@DancesWithMice.info>
Message-ID: <CAEFLyb+ANWncQ1sAc3EmZMaf88_Hw-sBqwDxXuARWmFeiOjr=w@mail.gmail.com>

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 <tutor at python.org> 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: <CAEFLyb+ANWncQ1sAc3EmZMaf88_Hw-sBqwDxXuARWmFeiOjr=w@mail.gmail.com>
References: <CAEFLybKyGrxSHsBNZ517eE1NOMqLdDtvBgB1WH=hs0B9s5R3uw@mail.gmail.com>
 <a8769628-859b-9b16-0228-42a255bd059c@DancesWithMice.info>
 <CAEFLyb+ANWncQ1sAc3EmZMaf88_Hw-sBqwDxXuARWmFeiOjr=w@mail.gmail.com>
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