From arj.python at gmail.com  Tue Dec  1 02:26:52 2020
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Tue, 1 Dec 2020 11:26:52 +0400
Subject: [Tutor] Recommendation to supersede openpyxl
In-Reply-To: <rq3lkf$6rr$1@ciao.gmane.io>
References: <tencent_EC107164D26B1BD5E5E7A6898827A85B8B05@qq.com>
 <rq2pek$t45$1@ciao.gmane.io> <6jfasfh0pldror3e7cehf8h9t7297jq0dn@4ax.com>
 <rq3lkf$6rr$1@ciao.gmane.io>
Message-ID: <CADrxXX=BO+fvtrjW5bMN-7YB9isz8V24+EaCUb8rKUnOF9C84Q@mail.gmail.com>

Greetings list,

Just a PyAutoGui note:

If you are using it to open menus via mouse coordinates,
just be aware that this might change on another computer!

Kind Regards,

Abdur-Rahmaan Janhangeer
about <https://compileralchemy.github.io/> | blog
<https://abdur-rahmaanj.github.io/>
github <https://github.com/Abdur-RahmaanJ>
Mauritius

>
>

From alvarodorsnestares at gmail.com  Tue Dec  1 10:41:20 2020
From: alvarodorsnestares at gmail.com (=?UTF-8?Q?=C3=81lvaro_d=27Ors?=)
Date: Tue, 1 Dec 2020 16:41:20 +0100
Subject: [Tutor] IDLE
Message-ID: <CAFnUUMkGsaT3N0c+QZa6hHVbprJYSLYbmL1x38_bTWGasCwwjQ@mail.gmail.com>

I can't open the IDLE, I've tried everything on internet but I just can't.
It doesn't even give any error message and I've re-installed it more than
10 times. Please help.

-- 
Nestares D. ?lvaro

From alan.gauld at yahoo.co.uk  Tue Dec  1 13:08:54 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 1 Dec 2020 18:08:54 +0000
Subject: [Tutor] IDLE
In-Reply-To: <CAFnUUMkGsaT3N0c+QZa6hHVbprJYSLYbmL1x38_bTWGasCwwjQ@mail.gmail.com>
References: <CAFnUUMkGsaT3N0c+QZa6hHVbprJYSLYbmL1x38_bTWGasCwwjQ@mail.gmail.com>
Message-ID: <rq60rn$8ml$1@ciao.gmane.io>

On 01/12/2020 15:41, ?lvaro d'Ors wrote:
> I can't open the IDLE, I've tried everything on internet but I just can't.
> It doesn't even give any error message and I've re-installed it more than
> 10 times. Please help.


OK,
Which OS version and Python version are you using?
How exactly are you trying to run IDLE?
Have you located the idle files on your computer?
Where are they?


-- 
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 phillor9 at gmail.com  Tue Dec  1 19:10:34 2020
From: phillor9 at gmail.com (Phil)
Date: Wed, 2 Dec 2020 11:10:34 +1100
Subject: [Tutor] Mapping memory coordinate to screen coordinates
Message-ID: <23586c1a-11de-ab45-a2e0-984f7e7547c9@gmail.com>

Thank you for looking at this lengthy example.

Over the years I've used this scheme to display a memory grid using C++ 
and more recently Python. The problem is that the x and y coordinates 
don't match the screen coordinates. The simple solution is to reverse 
either the grid or screen coordinates, however this leads to confusion. 
I'm currently working on, what to me, is a complex game board and I'm 
constantly running into bugs because I'm confusing the screen 
coordinates with the real coordinates and mental gymnastics is something 
the I'm struggling with as I age.

I came across the following example a couple of days ago and it shows 
the problem perfectly. Can anyone suggest a logical solution where 
memory grid[x][y] is the same as screen grid[x]y]?


"""
 ?Example program to show using an array to back a grid on-screen.

 ?Sample Python/Pygame Programs
 ?Simpson College Computer Science
 ?http://programarcadegames.com/
 ?http://simpson.edu/computer-science/

 ?Explanation video: http://youtu.be/mdTeqiWyFnc
"""
import pygame

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 20
HEIGHT = 20

# This sets the margin between each cell
MARGIN = 5

# Create a 2 dimensional array. A two dimensional
# array is simply a list of lists.
grid = []
for row in range(10):
 ??? # Add an empty array that will hold each cell
 ??? # in this row
 ??? grid.append([])
 ??? for column in range(10):
 ??????? grid[row].append(0)? # Append a cell

# Set row 1, cell 5 to one. (Remember rows and
# column numbers start at zero.)

'''
****************************************************

This demonstrates the problem ; x and y are reversed

****************************************************
'''
grid[1][5] = 1

# Initialize pygame
pygame.init()

# Set the HEIGHT and WIDTH of the screen
WINDOW_SIZE = [255, 255]
screen = pygame.display.set_mode(WINDOW_SIZE)

# Set title of screen
pygame.display.set_caption("Array Backed Grid")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop -----------
while not done:
 ??? for event in pygame.event.get():? # User did something
 ??????? if event.type == pygame.QUIT:? # If user clicked close
 ??????????? done = True? # Flag that we are done so we exit this loop
 ??????? elif event.type == pygame.MOUSEBUTTONDOWN:
 ??????????? # User clicks the mouse. Get the position
 ??????????? pos = pygame.mouse.get_pos()
 ??????????? # Change the x/y screen coordinates to grid coordinates
 ??????????? column = pos[0] // (WIDTH + MARGIN)
 ??????????? row = pos[1] // (HEIGHT + MARGIN)
 ??????????? # Set that location to one
 ??????????? grid[row][column] = 1
 ??????????? print("Click ", pos, "Grid coordinates: ", row, column)

 ??? # Set the screen background
 ??? screen.fill(BLACK)

 ??? # Draw the grid
 ??? for row in range(10):
 ??????? for column in range(10):
 ??????????? color = WHITE
 ??????????? if grid[row][column] == 1:
 ??????????????? color = GREEN
 ??????????? pygame.draw.rect(screen,
 ???????????????????????????? color,
 ???????????????????????????? [(MARGIN + WIDTH) * column + MARGIN,
 ????????????????????????????? (MARGIN + HEIGHT) * row + MARGIN,
 ????????????????????????????? WIDTH,
 ????????????????????????????? HEIGHT])

 ??? # Limit to 60 frames per second
 ??? clock.tick(60)

 ??? # Go ahead and update the screen with what we've drawn.
 ??? pygame.display.flip()

# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit()

-- 
Regards,
Phil


From manpritsinghece at gmail.com  Tue Dec  1 21:33:41 2020
From: manpritsinghece at gmail.com (Manprit Singh)
Date: Wed, 2 Dec 2020 08:03:41 +0530
Subject: [Tutor] Function decorators
In-Reply-To: <rq39e7$goq$1@ciao.gmane.io>
References: <CAO1OCwZM3HTMRBXiYucXg24C+ekVJZUTyAJFs+iQyu-J77m5OQ@mail.gmail.com>
 <rq39e7$goq$1@ciao.gmane.io>
Message-ID: <CAO1OCwaowTGcsVWNo1jgnzpHcpT=d+UFcBCaN_dd3NgpTS+YwQ@mail.gmail.com>

Dear  sir ,

Below written is the code for the question given by you in your last mail .

For example can you, without considering decorators,
define a function that returns a new function that
will calculate a given power?


>>> def exponent_builder2(x):
           def ypowx(y):
               return y**x
           return ypowx

>>> sqr = exponent_builder2(2)
>>> sqr(7)  # will give 47
49

cube = exponent_builder2(3)
>>> cube(3)  #will give 27
27

This definition can be written in more easy way with lambda expression  as
below:

>>> def exponent_builder(x):
           return lambda y: y**x

So,what  is the next exercise for me to understand the function
decorators?  the code written above by me is correct ? kindly let me know

Regards
Manprit Singh








On Mon, Nov 30, 2020 at 10:47 PM Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 30/11/2020 14:39, Manprit Singh wrote:
> > I tried to understand the concept of function decorators from various
> > sources but couldn't .
>
> They are a fairly advanced concept that is rarely
> used (as in creating decorators) in every day programming.
> Decorators are easy enough to use once created even if you
> don't understand what they do under the covers.
> But creating a decorator is slightly more complex.
>
> In essence a decorator is a function that returns
> a function and then gets called through a bit of
> Python syntactical magic - the @prefix.
>
> Before understanding decorators do you understand
> the concept of functions as objects? Are you
> comfortable with lambdas? Lambdas aren't needed
> for decorators but if you understand what lambdas
> do you will find it a shorter step to decorators.
>
> For example can you, without considering decorators,
> define a function that returns a new function that
> will calculate a given power?
>
> def exponent_builder(n)
>     def f(....
>     return f
>
> square = exponent_builder(2)
> print(square(7) )   -> prints 49
>
> triple = exponent_builder(3)
> print( triple(3))  -> prints 27
>
> If you can write exponent_builder() you are well
> on the way to writing a decorator.
>
> > I am sorry if I said something wrong.
>
> No, it's a reasonable question. You will need to
> be more specific now in any follow-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
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From PyTutor at danceswithmice.info  Tue Dec  1 22:12:50 2020
From: PyTutor at danceswithmice.info (dn)
Date: Wed, 2 Dec 2020 16:12:50 +1300
Subject: [Tutor] Mapping memory coordinate to screen coordinates
In-Reply-To: <23586c1a-11de-ab45-a2e0-984f7e7547c9@gmail.com>
References: <23586c1a-11de-ab45-a2e0-984f7e7547c9@gmail.com>
Message-ID: <91a36cf7-d3f2-e0e7-74ea-53ba75961399@DancesWithMice.info>

On 02/12/2020 13:10, Phil wrote:
> Thank you for looking at this lengthy example.
> 
> Over the years I've used this scheme to display a memory grid using C++ 
> and more recently Python. The problem is that the x and y coordinates 
> don't match the screen coordinates. The simple solution is to reverse 
> either the grid or screen coordinates, however this leads to confusion. 
> I'm currently working on, what to me, is a complex game board and I'm 
> constantly running into bugs because I'm confusing the screen 
> coordinates with the real coordinates and mental gymnastics is something 
> the I'm struggling with as I age.
> 
> I came across the following example a couple of days ago and it shows 
> the problem perfectly. Can anyone suggest a logical solution where 
> memory grid[x][y] is the same as screen grid[x]y]?
...


I've been using Python for a long time, but only looked at Turtles and 
pygame quite recently. (second childhood perhaps?)


I'm (largely) ignoring the code (and thus the question as-asked), in 
favor of examining the design issue which 'creates' these problems - 
described as "reverse".

Pygame is a 'framework'. When we choose to utilise a framework (or in 
making the choice of one over some-other) considerations should include 
the assumptions and philosophies upon which the code has been built. For 
example, mathematicians and physicists often tackle the same 
calculations quite differently and with their own terminology for the 
very same 'thing' - go figure! Best to choose something which 'speaks' 
your own language, thinks the way you do, ...

In this case, pygame treats the Origin (co-ordinates: 0, 0) as the 
top-left pixel of the screen. Many other graphics-tools place the Origin 
at either the bottom-left, or at the center of, the 
screen/window/surface/graph.

Accordingly, there is an implicit expectation that if we wish to model 
something using pygame, we will accept that 
characteristic/advantage/limitation! This, in the same way that we 
(eventually) accept whichever side of a car has the steering-wheel, 
whether the wind-shield-wipers or lights are on the left/right 'stalk', 
and whether the key turns clockwise to lock - or anti-clockwise. (the 
two cars I use most-often are opposites in the latter case. Grrrr!)

Almost all of us will accept the tool the way it is. Sure, there are 
some who might rip the car apart in order to reassemble it 'perfectly', 
but...
(see also "open source" and "forking" software!)

Accordingly, choice nr1: adapt your thinking to become compatible and 
congruent with the philosophies and conventions of the tool. This the 
other way around: find a tool that works the way you do...


However, it is difficult to see the world only one-way. Indeed, if/when 
you move into 3-D graphics (and coordinates) there are two 'competing' 
approaches: "left-handed" and (wait for it...) "right-handed" coordinate 
systems. As you are probably thinking with the question above, sometimes 
'the math' becomes a lot easier when we use one, rather than contorting 
ourselves to cope with the other!

This is not limited to (computer)graphics by any means. How about the 
famous "computer-error" where a space-mission went drastically wrong 
because one team had been working in metric-units whilst their 
colleagues used "imperial". Similarly, when will we all agree on Celsius 
or Fahrenheit (etc) temperature scales; distances in feet or 
meters/metres;  colors represented as RGB[a] or HSL (also, etc) - and 
the band marches on...


Thus, let's move to consider choice nr2. If you cannot, or will not, 
alter your thinking to suit pygame; then just as the temperature 
'problem' mentioned earlier is a very common 'my first program[me]' 
assignment in schools, you could consider building an "interface".

This requires us to consider that there are two separate, but somehow 
related, entities: the "grid" or 'map' of your world; and the pygame 
surface. They will both represent exactly the same information, but the 
former will be lists and values, but the latter screen-bytes/pixels.

NB on the subject of "related": the provided-code already confuses 
because the grid has a width/height (and margins), quite different to 
the 255x255 size of the surface! Would it be easier to grid only the 
'working' part of the image?

Plus, each will (presumably) be a (logical) mirror-image of the other 
(jargon: "reflection" about the horizontal/vertical center of the 
grid/surface).

The purpose of the "interface" will be to take abstract-content from 
your "grid" and have that displayed 'wrong-way up' on the screen. 
Conversely, it will also need to take the likes of mouse-locations from 
the surface, and re-compute them become 'equivalent' coordinates on the 
grid.

Thus ( 0, 0 ) on your grid might become ( 0, surface_height ) in pygame, 
and pygame's bottom-right pixel ( surface_width, surface_height ) will 
become ( max_width, 0 ) on the grid.

Looking at the code-provided, I suggest that "the interface" be 
implemented as two functions:
	grid_to_surface( x:int, y:int )->Tuple( int )   # int or float
and
	surface_to_grid( position:tuple )->Tuple( int )

Now, the calculations can be abstracted away from the "event loop", and 
thus will be available for use in however-many cases without 
code-repetition, eg if/when it is necessary to check if an object should 
'bounce' of a wall or if a missile has impacted its target...

NB (WIDTH + MARGIN) and (HEIGHT + MARGIN) already appear more than once! 
(worse: is expressed inconsistently).

NBB I would be thinking of using at least one class (to represent the 
screen/surface "entity", ie including the set_mode() declaration and 
other screen-parameters) as well as containing the encode/decode 
interface routines (methods); if such suits your own way of 
thinking/coding, and doesn't conflict with the procedural thinking 
implicit in event-loops...


If some of the discussion (above) feels a little advanced for your 
personal stage and progress with Python, then may I recommend adapting 
yourself to "choice nr1" - even if more effort 'now', it will make your 
continuing use of pygame less fraught!

If you already 'know the graphics' (perhaps even to the code-level/are 
adapting to Python and/or pygame) but are being frustrated by the tool, 
then "choice nr2" may be the way to go...
-- 
Regards =dn

From cs at cskk.id.au  Tue Dec  1 23:35:59 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 2 Dec 2020 15:35:59 +1100
Subject: [Tutor] Function decorators
In-Reply-To: <CAO1OCwaowTGcsVWNo1jgnzpHcpT=d+UFcBCaN_dd3NgpTS+YwQ@mail.gmail.com>
References: <CAO1OCwaowTGcsVWNo1jgnzpHcpT=d+UFcBCaN_dd3NgpTS+YwQ@mail.gmail.com>
Message-ID: <20201202043559.GA77918@cskk.homeip.net>

On 02Dec2020 08:03, Manprit Singh <manpritsinghece at gmail.com> wrote:
>For example can you, without considering decorators,
>define a function that returns a new function that
>will calculate a given power?
>
>>>> def exponent_builder2(x):
>           def ypowx(y):
>               return y**x
>           return ypowx
>
>>>> sqr = exponent_builder2(2)
>>>> sqr(7)  # will give 47
>49
>
>cube = exponent_builder2(3)
>>>> cube(3)  #will give 27
>27
>
>This definition can be written in more easy way with lambda expression  as
>below:
>
>>>> def exponent_builder(x):
>           return lambda y: y**x
>
>So,what  is the next exercise for me to understand the function
>decorators?  the code written above by me is correct ? kindly let me 
>know

The code's correct. A lambda is just a terse way to write a single 
expression function. You need the 'def" form when you have internal 
logic which can't be expressed in a single expression, or not expressed 
well.

So, to decorators: a decorator is like your functions above, which 
return a function. However, they _accept_ a function as their argument, 
and return a function to use in its place. Often that returned function 
calls the original function in some way.

So consider this:

    def trace(func):
        def tracer(*a, **kw):
            print("calling", func)
            value = func(*a, **kw)
            print("called", func, "result", value)
            return value
        return tracer

This defines a function "tracer" which prints a message, calls the 
_original_ function with tha same arguments handed to "tracer", then 
prints the result and returns the result.

Then we return that "tracer" function, just as you returned "ypowx" 
above.

So if you defined some basic function like this:

    def square(x):
        return x*x

You could rebind the name "square" like this:

    square = trace(square)

Now when you call "square" you call the function returned by trace(), 
which does some print() calls around the inner call to the original 
square() function. In effect, the "square" function is now traced, so 
that you can see uses of it.

The reason these are called decorators is that Python has a special 
syntax like this:

    @trace
    def square(x):
        return x*x

which is equivalent to going:

    def square(x):
        return x*x
    square = trace(square)

so that the original function is 'decorated' by "@trace".

The returned function doesn't need to call the original function exactly 
as it itself was called, not return its value unchanged. You might 
adjust any of these depending on what you need.

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

From alan.gauld at yahoo.co.uk  Wed Dec  2 03:57:54 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 2 Dec 2020 08:57:54 +0000
Subject: [Tutor] Fwd: Re: Mapping memory coordinate to screen coordinates
In-Reply-To: <758acf3b-6b17-7bf9-53f0-106d8e29faea@yahoo.co.uk>
References: <758acf3b-6b17-7bf9-53f0-106d8e29faea@yahoo.co.uk>
Message-ID: <eb648b72-6be8-5f7b-62e1-d22c20341f39@yahoo.co.uk>

I seem to have sent this just to Phil. Forwarding to list...



On 02/12/2020 00:10, Phil wrote:

> I came across the following example a couple of days ago and it shows
> the problem perfectly. Can anyone suggest a logical solution where
> memory grid[x][y] is the same as screen grid[x]y]?

My usual solution to these kind of issues is replace grid
with a dictionary keyed by x,y tuples.

If that's too simplistic then I'd create a grid class
with indexing implemented such that the coordinates
get reversed. But a dictionary is easier if you just
need data accessed by x,y

rows,cols = 4,4
grid = dict()
for row in range(rows):
for col in range(cols):
grid[col,row] = 0 #initialise.

#print column 3:
for row in range(rows):
print( grid[3,row] )

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 arj.python at gmail.com  Wed Dec  2 04:13:31 2020
From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer)
Date: Wed, 2 Dec 2020 13:13:31 +0400
Subject: [Tutor] Function decorators
In-Reply-To: <CAO1OCwZM3HTMRBXiYucXg24C+ekVJZUTyAJFs+iQyu-J77m5OQ@mail.gmail.com>
References: <CAO1OCwZM3HTMRBXiYucXg24C+ekVJZUTyAJFs+iQyu-J77m5OQ@mail.gmail.com>
Message-ID: <CADrxXXkxfAay_QurCDxdniA+gHjzgGyS-XtfN1O=H_mh3giWOQ@mail.gmail.com>

I have this slide:

https://speakerdeck.com/osdotsystem/python-decorating-your-code

which i presented at our local Python
meetup

it should be easy to follow as i kind
of derive it

Kind Regards,


Abdur-Rahmaan Janhangeer

https://www.github.com/Abdur-RahmaanJ

Mauritius

sent from gmail client on Android, that's why the signature is so ugly.

On Mon, 30 Nov 2020, 18:39 Manprit Singh, <manpritsinghece at gmail.com> wrote:

> Dear sir,
>
> I tried to understand the concept of function decorators from various
> sources but couldn't .
>
> Can i request you a small text that describes the decorators along with an
> example .
>
> I am sorry if I said something wrong.
>
> Regards
> Manprit singh
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From spitzt at purdue.edu  Wed Dec  2 10:19:23 2020
From: spitzt at purdue.edu (Spitz, Tobias)
Date: Wed, 2 Dec 2020 15:19:23 +0000
Subject: [Tutor] pygame troubles
Message-ID: <SA0PR22MB2144CC689BA76812FB56ECB4B3F30@SA0PR22MB2144.namprd22.prod.outlook.com>

Good morning!
My name is Tobias, I've been trying to recreate minesweeper in python following a Youtube tutorial(https://www.youtube.com/watch?v=AI2zs3nKHgg&t=6s) but hit a wall when trying to display the game window. Whenever I run the code, the window pops up with the correct number of tiles however they are separated and I am unable to interact with them. I thought the issue would be due to a image error where the images are the incorrect size or something, but Im not sure why I wouldn't be able to interact with the code. There's also a "restart" statement where hitting a letter "R" would restart the game but since the game doesn't seem to work in the beginning, the error must be before that statement.

I've attached all the image files and code below. I would be forever grateful if I could receive some help on this.
Have a wonderful Wednesday!

Sincerely,
Tobias Spitz


From mats at wichmann.us  Wed Dec  2 11:25:46 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Wed, 2 Dec 2020 09:25:46 -0700
Subject: [Tutor] pygame troubles
In-Reply-To: <SA0PR22MB2144CC689BA76812FB56ECB4B3F30@SA0PR22MB2144.namprd22.prod.outlook.com>
References: <SA0PR22MB2144CC689BA76812FB56ECB4B3F30@SA0PR22MB2144.namprd22.prod.outlook.com>
Message-ID: <12a8032d-461b-c552-a075-ab7041bfdfa6@wichmann.us>

On 12/2/20 8:19 AM, Spitz, Tobias wrote:
> Good morning!
> My name is Tobias, I've been trying to recreate minesweeper in python following a Youtube tutorial(https://www.youtube.com/watch?v=AI2zs3nKHgg&t=6s) but hit a wall when trying to display the game window. Whenever I run the code, the window pops up with the correct number of tiles however they are separated and I am unable to interact with them. I thought the issue would be due to a image error where the images are the incorrect size or something, but Im not sure why I wouldn't be able to interact with the code. There's also a "restart" statement where hitting a letter "R" would restart the game but since the game doesn't seem to work in the beginning, the error must be before that statement.
> 
> I've attached all the image files and code below. I would be forever grateful if I could receive some help on this.
> Have a wonderful Wednesday!

Sadly, it's a text-only list, so attachments get stripped. You can see 
what your message looked like here:

https://mail.python.org/pipermail/tutor/2020-December/117801.html

so you'll need to resend with more information inline.


From phillor9 at gmail.com  Wed Dec  2 18:06:24 2020
From: phillor9 at gmail.com (Phil)
Date: Thu, 3 Dec 2020 10:06:24 +1100
Subject: [Tutor] Mapping memory coordinate to screen coordinates
In-Reply-To: <fopfsfhgugqni4arjngcna2h5cji6rqs6m@4ax.com>
References: <23586c1a-11de-ab45-a2e0-984f7e7547c9@gmail.com>
 <fopfsfhgugqni4arjngcna2h5cji6rqs6m@4ax.com>
Message-ID: <a3e0b394-0b74-7fbe-b683-a660cd4f4103@gmail.com>

On 3/12/20 7:35 am, Dennis Lee Bieber wrote:
> In computer graphics textbooks, what you have encountered is a
> difference between World Coordinates and (Normalized) Device Coordinates
> (there is typically an intermediate of "Viewport Coordinates" covered in
> the texts too). One has to go through a transformation going from one to
> the other.

Thank you Dennis for searching for the links on transformation. I 
normally think of transformation in the context of rotating a 3D object, 
for example. My current problem is nowhere near as complex and simply 
involves swapping the x and y coordinates, [y][x] instead of [x][y]. I 
think a grid class, as suggested, would be a helpful solution. I will 
study the content of the links.

Thank you Alan for an alternative to a list of lists, I haven't made 
much use of dictionaries. I'll give it some thought.

Thank you dn for your report. I hadn't considered that I maybe guilty of 
ridged thinking. However, I do seem to get stuck in circular pattern 
when trying to solve a problem so your suggestion probably has some merit.

By the way, the pygame example is just something that I came across, it 
illustrates the problem well. My current project is built using the 
wxPython GUI library.

-- 

Regards,
Phil


From s.molnar at sbcglobal.net  Sun Dec  6 08:37:18 2020
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Sun, 6 Dec 2020 08:37:18 -0500
Subject: [Tutor] Extract element of dtype object
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
Message-ID: <5FCCDE8E.1090205@sbcglobal.net>

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

This is an example or a portion of the file:

mode |   affinity | dist from best mode
      | (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
    1    -8.538750714      0.000      0.000
    2    -8.487003690      3.712      7.079
    3    -8.420436250      3.018      6.604
    4    -7.992952187      3.711      7.282
    5    -7.933139639      2.128      6.739
    6    -7.889517329      2.667      6.537
    7    -7.720785374     20.143     23.808
    8    -7.629772565     21.218     25.083
    9    -7.560349273      2.136      7.865
Writing output ... done.

and the code snippet:

Refining results ... done.

0 mode | affinity | dist from best mode

1 | (kcal/mol) | rmsd l.b.| rmsd u.b.

2 -----+------------+----------+----------

3 1 -8.538750714 0.000 0.000

4 2 -8.487003690 3.712 7.079

the output:

Refining results ... done. 1 -8.538750714 0.000 0.000


                    Refining results ... done.
0     mode |   affinity | dist from best mode
1         | (kcal/mol) | rmsd l.b.| rmsd u.b.
2    -----+------------+----------+----------
3     1           0.000      0.000
4     2    -8.487003690      3.712      7.079
Refining results ... done.       1    -8.538750714      0.000 0.000
Name: 3, dtype: object

The number that I want to extract is -8.538750714.

To this point, google has not been a friend. I'm reasonably sure that I 
am not asking google the correct question. My question to the list is 
'What is the question?' that will solve my problem??

Thanks in advance.

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


From mats at wichmann.us  Sun Dec  6 11:28:27 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 6 Dec 2020 09:28:27 -0700
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <5FCCDE8E.1090205@sbcglobal.net>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
Message-ID: <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>

On 12/6/20 6:37 AM, Stephen P. Molnar wrote:
> I have a large number of files from which I wish to extract a number.

Your succession of examples is not leaving me, at least, with any 
clarity of what you're actually looking for.  You need to define for 
yourself a description in words, then you can probably begin to code it 
up. Youi include "and the code snippet" but there is no code snippet...

see below

> 
> This is an example or a portion of the file:
> 
> mode |?? affinity | dist from best mode
>  ???? | (kcal/mol) | rmsd l.b.| rmsd u.b.
> -----+------------+----------+----------
>  ?? 1??? -8.538750714????? 0.000????? 0.000
>  ?? 2??? -8.487003690????? 3.712????? 7.079
>  ?? 3??? -8.420436250????? 3.018????? 6.604
>  ?? 4??? -7.992952187????? 3.711????? 7.282
>  ?? 5??? -7.933139639????? 2.128????? 6.739
>  ?? 6??? -7.889517329????? 2.667????? 6.537
>  ?? 7??? -7.720785374???? 20.143???? 23.808
>  ?? 8??? -7.629772565???? 21.218???? 25.083
>  ?? 9??? -7.560349273????? 2.136????? 7.865
> Writing output ... done.
> 
> and the code snippet:
> 
> Refining results ... done.
> 
> 0 mode | affinity | dist from best mode
> 
> 1 | (kcal/mol) | rmsd l.b.| rmsd u.b.
> 
> 2 -----+------------+----------+----------
> 
> 3 1 -8.538750714 0.000 0.000
> 
> 4 2 -8.487003690 3.712 7.079
> 
> the output:
> 
> Refining results ... done. 1 -8.538750714 0.000 0.000
> 
> 
>  ?????????????????? Refining results ... done.
> 0???? mode |?? affinity | dist from best mode
> 1???????? | (kcal/mol) | rmsd l.b.| rmsd u.b.
> 2??? -----+------------+----------+----------
> 3???? 1?????????? 0.000????? 0.000
> 4???? 2??? -8.487003690????? 3.712????? 7.079
> Refining results ... done.?????? 1??? -8.538750714????? 0.000 0.000
> Name: 3, dtype: object
> 
> The number that I want to extract is -8.538750714.

If you're collecting lines from running an external script, you can run 
that script with subprocess.run and then look through the resulting 
output until you find a line that matches some recognizable pattern. 
That pattern seems to be "Refining results ... done." but it appears so 
many times in the above it's hard to sort out what's what. If that's the 
case you can then trim that line either with plain string handling 
routines or with a regular expression (regexes get a bad reputation, 
they're good for handling text with recognizable patterns, but may be 
overkill for this case)

Will wait for some clarification before digging further...



From s.molnar at sbcglobal.net  Sun Dec  6 12:31:02 2020
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Sun, 6 Dec 2020 12:31:02 -0500
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
 <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
Message-ID: <5FCD1556.4030107@sbcglobal.net>



On 12/06/2020 11:28 AM, Mats Wichmann wrote:
> On 12/6/20 6:37 AM, Stephen P. Molnar wrote:
>> I have a large number of files from which I wish to extract a number.
>
> Your succession of examples is not leaving me, at least, with any 
> clarity of what you're actually looking for.  You need to define for 
> yourself a description in words, then you can probably begin to code 
> it up. Youi include "and the code snippet" but there is no code 
> snippet...
>
> see below
>
>>
>> This is an example or a portion of the file:
>>
>> mode |   affinity | dist from best mode
>>       | (kcal/mol) | rmsd l.b.| rmsd u.b.
>> -----+------------+----------+----------
>>     1    -8.538750714      0.000      0.000
>>     2    -8.487003690      3.712      7.079
>>     3    -8.420436250      3.018      6.604
>>     4    -7.992952187      3.711      7.282
>>     5    -7.933139639      2.128      6.739
>>     6    -7.889517329      2.667      6.537
>>     7    -7.720785374     20.143     23.808
>>     8    -7.629772565     21.218     25.083
>>     9    -7.560349273      2.136      7.865
>> Writing output ... done.
>>
>> and the code snippet:
>>
>> Refining results ... done.
>>
>> 0 mode | affinity | dist from best mode
>>
>> 1 | (kcal/mol) | rmsd l.b.| rmsd u.b.
>>
>> 2 -----+------------+----------+----------
>>
>> 3 1 -8.538750714 0.000 0.000
>>
>> 4 2 -8.487003690 3.712 7.079
>>
>> the output:
>>
>> Refining results ... done. 1 -8.538750714 0.000 0.000
>>
>>
>>                     Refining results ... done.
>> 0     mode |   affinity | dist from best mode
>> 1         | (kcal/mol) | rmsd l.b.| rmsd u.b.
>> 2    -----+------------+----------+----------
>> 3     1           0.000      0.000
>> 4     2    -8.487003690      3.712      7.079
>> Refining results ... done.       1    -8.538750714      0.000 0.000
>> Name: 3, dtype: object
>>
>> The number that I want to extract is -8.538750714.
>
> If you're collecting lines from running an external script, you can 
> run that script with subprocess.run and then look through the 
> resulting output until you find a line that matches some recognizable 
> pattern. That pattern seems to be "Refining results ... done." but it 
> appears so many times in the above it's hard to sort out what's what. 
> If that's the case you can then trim that line either with plain 
> string handling routines or with a regular expression (regexes get a 
> bad reputation, they're good for handling text with recognizable 
> patterns, but may be overkill for this case)
>
> Will wait for some clarification before digging further...
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
Oh oh. Here is the code:

import pandas as pd

df = pd.read_table('test.log')
df = df.dropna(axis=1)
print(df.head())

x = (df.iloc[3])
print(x)

from the origional post

This is an example or a portion of the file:

mode |   affinity | dist from best mode
       | (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
     1    -8.538750714      0.000      0.000
          ^^^^^^^^^
           | |  |  | |  | | | |
          this is the number I want to extract.

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


From mats at wichmann.us  Sun Dec  6 14:29:46 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Sun, 6 Dec 2020 12:29:46 -0700
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <5FCD1556.4030107@sbcglobal.net>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
 <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
 <5FCD1556.4030107@sbcglobal.net>
Message-ID: <9a03fe52-a7a9-d89e-3b88-390d26a58de1@wichmann.us>

On 12/6/20 10:31 AM, Stephen P. Molnar wrote:

> Oh oh. Here is the code:
> 
> import pandas as pd
> 
> df = pd.read_table('test.log')
> df = df.dropna(axis=1)
> print(df.head())
> 
> x = (df.iloc[3])
> print(x)
> 
> from the origional post
> 
> This is an example or a portion of the file:
> 
> mode |?? affinity | dist from best mode
>  ????? | (kcal/mol) | rmsd l.b.| rmsd u.b.
> -----+------------+----------+----------
>  ??? 1??? -8.538750714????? 0.000????? 0.000
>  ???????? ^^^^^^^^^
>  ????????? | |? |? | |? | | | |
>  ???????? this is the number I want to extract.

If this is consistent behavior it's very easy.  e.g.:

 >>> line = '    1    -8.538750714      0.000      0.000'
 >>> fields = line.split()
 >>> print(fields)
['1', '-8.538750714', '0.000', '0.000']
 >>> print(fields[1])
-8.538750714
 >>>

but... it seems you aren't reading the line directly, but using Pandas? 
Don't use that myself, but if you process it correctly, it probably 
already knows all of this, and you just need to figure out how it stores 
it...

and if the data lines don't always look the same, then you need to get 
more clever at identifying commonality. i.e. that number you're looking 
for seems to appear in a lot of different ways from your original email...


From breamoreboy at gmail.com  Sun Dec  6 09:23:13 2020
From: breamoreboy at gmail.com (Mark Lawrence)
Date: Sun, 6 Dec 2020 14:23:13 +0000
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <5FCCDE8E.1090205@sbcglobal.net>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
Message-ID: <1cdd8cdc-e5e4-ad1b-7339-43b25ba54840@gmail.com>

On 06/12/2020 13:37, Stephen P. Molnar wrote:
> I have a large number of files from which I wish to extract a number.
> 
  [big snip]

> 3???? 1?????????? 0.000????? 0.000
> 4???? 2??? -8.487003690????? 3.712????? 7.079
> Refining results ... done.?????? 1??? -8.538750714????? 0.000 0.000
> Name: 3, dtype: object
> 
> The number that I want to extract is -8.538750714.
> 
> To this point, google has not been a friend. I'm reasonably sure that I 
> am not asking google the correct question. My question to the list is 
> 'What is the question?' that will solve my problem??

Something like 'python read data from file' for starters.  Having done 
that you'll probably need something like this 
https://docs.python.org/3/library/stdtypes.html#str.split

> 
> Thanks in advance.
> 

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at yahoo.co.uk  Sun Dec  6 16:08:03 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 6 Dec 2020 21:08:03 +0000
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <5FCCDE8E.1090205@sbcglobal.net>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
Message-ID: <rqjh7j$8vi$1@ciao.gmane.io>

On 06/12/2020 13:37, Stephen P. Molnar wrote:
> I have a large number of files from which I wish to extract a number.

Just one number?
Or a field from each line that happens to be a number?

The two scenarios have very different solutions.

If its a field (and you are on a *nix OS) consider using
[g]awk, its designed for that kind of thing

$ gawk '/^[ 0-9]+/ print {$4}' myfile.txt

prints the 4th field on any liner starting with a number

But do you need a key too? - like the line number say?

> This is an example or a portion of the file:
> -----+------------+----------+----------
>     1    -8.538750714      0.000      0.000
>     2    -8.487003690      3.712      7.079
>     3    -8.420436250      3.018      6.604
>     4    -7.992952187      3.711      7.282
>     5    -7.933139639      2.128      6.739

> 3 1 -8.538750714 0.000 0.000
> 4 2 -8.487003690 3.712 7.079
> 
> the output:
> 
> Refining results ... done. 1 -8.538750714 0.000 0.000

How can you tell that line is the one you want?
There must be some other criteria?
Or is it that particular number you want - in which
case the solution is trivial.

> The number that I want to extract is -8.538750714.

We need a more precise  description of the problem,.
Precisely expressed requirements lead to precisely
expressed solutions. Vague requirements lead to an
array of confusing possibilities.

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



From s.molnar at sbcglobal.net  Mon Dec  7 13:10:24 2020
From: s.molnar at sbcglobal.net (Stephen P. Molnar)
Date: Mon, 7 Dec 2020 13:10:24 -0500
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <t8pssftck8o9h2b6sist1vee1dlvhmi3oa@4ax.com>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
 <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
 <5FCD1556.4030107@sbcglobal.net> <a4aqsf9r19ti4ohsqtld2egq4e8t4m22b2@4ax.com>
 <t8pssftck8o9h2b6sist1vee1dlvhmi3oa@4ax.com>
Message-ID: <5FCE7010.4000805@sbcglobal.net>



On 12/07/2020 12:55 PM, Dennis Lee Bieber wrote:
> 	o/~ Talking to myself in public o/~
>
> On Sun, 06 Dec 2020 14:33:06 -0500, Dennis Lee Bieber
> <wlfraed at ix.netcom.com> declaimed the following:
>
>
>> 	The best I can make out from the sketchy samples (the raw file contents
>> doesn't do much once pandas has imported it and you've created/edited the
>> resulting dataframe; seeing the dataframe as pandas displays it is more
>> useful). If your samples ARE as pandas displays them, then your input file
>> should be preprocessed as it has superfluous content that should not be
>> part of the data frame itself. Perhaps using /skiprows/ and /header/ should
>> be provided to the .read_table() call to ensure the data frame only has the
>> actual data (maybe: header=0, names=["mode", "affinity", "distance", ... ],
>> skiprows=3)
>>
>> 	
> 	Thoughts I had a few hours after that post...
>
> 	Is there any ICD/DDD* for the input file? That is, some document
> describing the detail format of the file, such that a new-hire programmer
> could write code to read/write that format, never having seen one before?
>
> 	At best, from what has been posted it appears to follow:
>
> I		The file is in readable text (?what encoding: ASCII, ISO-Latin-1,
> UTF8?)
>
> II		The file consists of a header section followed by data section
> 	A		The header section consists of three lines of text
> 		1		Line one consists of column labels delimited by |
> characters
> 		2		Line two consists of unit notations delimited by |
> characters
> 			a		Unit notations may be blank so long as there is a |
> delimiter placeholder
> 		3		Line three consists of + and - characters
> 			a		+ characters are used to mark column boundaries
> (aligned with the | characters of previous lines)
> 			b		- characters are used to span the gap between adjacent
> + characters
> 			c		The line exists merely for visual esthetics when
> viewing the file in a monospaced font
>
> 	B		The data section consists of one (is zero a viable file?) or
> more rows of numeric data delimited by TBD
> 		{the provided samples could be:
> 			1)	space filled fixed width fields: where is the width
> defined?
> 			2)	white-space delimited: does adjacent white-space collapse
> or does it indicate an empty field -- that is are:
> 				123<tab><tab>456
> 				123<tab>456
> 				to be treated as the same data, or does the first line
> contain three fields, the middle being empty?}
> 			3)	comma-separated (or some other visible delimiter -- which
> needs to be specified) {based upon the sample, this is not the case for
> this data}
>
>
> 	Note that the provided samples would confuse any CSV/TSV reading logic
> -- which is what I understand the pandas read logic uses internally. Many
> such readers attempt to interpret the format from the first couple of rows,
> and attempt to extract column headers from the first row.  Actually,
> looking at the original post -- there is a column label that spans TWO data
> columns, so that is going to confuse things too!
>
> 	What such might interpret from the sample file is that the data is |
> delimited (from the first two lines), and then fail to parse the actual
> data lines, as there are no | delimiters -- the entire data line would be
> treated as a single text string in column 1.
>
>
> 	Given the above hypothetical understanding of the input file, I'd
>
> 	Manually open the input file and read the first line of the header;
> close the file.
> 	Split that line on | characters, and strip any remaining spaces to get
> column labels {this won't handle the spanned columns properly -- you'd have
> to append another label for the second "dist" column"}
>
>>>> h1 = "mode |   affinity | dist from best mode"
>>>> h1.split("|")
> ['mode ', '   affinity ', ' dist from best mode']
>>>> [lbl.strip() for lbl in h1.split("|")]
> ['mode', 'affinity', 'dist from best mode']
> 	I would then pass that list of labels to the pandas read function while
> telling it to skip the first three lines of the file and to not attempt to
> parse a header. One might have to specify some other attribute to ensure
> the data rows are parsed properly if the file is not using commas or tabs
> to separate elements on each row.
>
>
>
>
>
> * Interface Control Document or Data Definition(Description) Document
>
>
Thanks for you detailed thoughts. I appreciate them.

I happen to be an Organic Chemist and Computers with some of their 
languages are among the many tools that I have used in the past 60 years 
or so. A a gauge of my logevity, the first langauge that I managed to 
butcher was FORTRAN II. Unfortunaly, a little bit of knowledge is a very 
dangerous thins and last for along time.

Thanks to the suggestions this this post has received, I came up with 
this code, which seems to give me what I was after'

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Mon Dec  7 06:49:04 2020

/home/comp/Apps/PythonDevelopment/ExtractData/ExtractDockData_4.py
"""
#pylint: disable = invalid-name
file = []
with open ('test_1.log', 'rt') as myfile:
     for myline in myfile:
         file.append(myline)
line = file[28]
print(line)
fields = line.split()
print(fields[1])

this results in:

runfile('/home/comp/Apps/PythonDevelopment/ExtractData/ExtractDockData_4.py', 
wdir='/home/comp/Apps/PythonDevelopment/ExtractData', 
current_namespace=True)
    1    -8.538750714      0.000      0.000

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


From mats at wichmann.us  Mon Dec  7 13:18:41 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Mon, 7 Dec 2020 11:18:41 -0700
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <5FCE7010.4000805@sbcglobal.net>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
 <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
 <5FCD1556.4030107@sbcglobal.net> <a4aqsf9r19ti4ohsqtld2egq4e8t4m22b2@4ax.com>
 <t8pssftck8o9h2b6sist1vee1dlvhmi3oa@4ax.com> <5FCE7010.4000805@sbcglobal.net>
Message-ID: <9682b9ab-9305-4444-b9ba-f6be08b72a47@wichmann.us>

On 12/7/20 11:10 AM, Stephen P. Molnar wrote:
> 
> 
> On 12/07/2020 12:55 PM, Dennis Lee Bieber wrote:
>> ????o/~ Talking to myself in public o/~
>>
>> On Sun, 06 Dec 2020 14:33:06 -0500, Dennis Lee Bieber
>> <wlfraed at ix.netcom.com> declaimed the following:
>>
>>
>>> ????The best I can make out from the sketchy samples (the raw file 
>>> contents
>>> doesn't do much once pandas has imported it and you've created/edited 
>>> the
>>> resulting dataframe; seeing the dataframe as pandas displays it is more
>>> useful). If your samples ARE as pandas displays them, then your input 
>>> file
>>> should be preprocessed as it has superfluous content that should not be
>>> part of the data frame itself. Perhaps using /skiprows/ and /header/ 
>>> should
>>> be provided to the .read_table() call to ensure the data frame only 
>>> has the
>>> actual data (maybe: header=0, names=["mode", "affinity", "distance", 
>>> ... ],
>>> skiprows=3)
>>>
>>>
>> ????Thoughts I had a few hours after that post...
>>
>> ????Is there any ICD/DDD* for the input file? That is, some document
>> describing the detail format of the file, such that a new-hire programmer
>> could write code to read/write that format, never having seen one before?
>>
>> ????At best, from what has been posted it appears to follow:
>>
>> I??????? The file is in readable text (?what encoding: ASCII, 
>> ISO-Latin-1,
>> UTF8?)
>>
>> II??????? The file consists of a header section followed by data section
>> ????A??????? The header section consists of three lines of text
>> ??????? 1??????? Line one consists of column labels delimited by |
>> characters
>> ??????? 2??????? Line two consists of unit notations delimited by |
>> characters
>> ??????????? a??????? Unit notations may be blank so long as there is a |
>> delimiter placeholder
>> ??????? 3??????? Line three consists of + and - characters
>> ??????????? a??????? + characters are used to mark column boundaries
>> (aligned with the | characters of previous lines)
>> ??????????? b??????? - characters are used to span the gap between 
>> adjacent
>> + characters
>> ??????????? c??????? The line exists merely for visual esthetics when
>> viewing the file in a monospaced font
>>
>> ????B??????? The data section consists of one (is zero a viable file?) or
>> more rows of numeric data delimited by TBD
>> ??????? {the provided samples could be:
>> ??????????? 1)??? space filled fixed width fields: where is the width
>> defined?
>> ??????????? 2)??? white-space delimited: does adjacent white-space 
>> collapse
>> or does it indicate an empty field -- that is are:
>> ??????????????? 123<tab><tab>456
>> ??????????????? 123<tab>456
>> ??????????????? to be treated as the same data, or does the first line
>> contain three fields, the middle being empty?}
>> ??????????? 3)??? comma-separated (or some other visible delimiter -- 
>> which
>> needs to be specified) {based upon the sample, this is not the case for
>> this data}
>>
>>
>> ????Note that the provided samples would confuse any CSV/TSV reading 
>> logic
>> -- which is what I understand the pandas read logic uses internally. Many
>> such readers attempt to interpret the format from the first couple of 
>> rows,
>> and attempt to extract column headers from the first row.? Actually,
>> looking at the original post -- there is a column label that spans TWO 
>> data
>> columns, so that is going to confuse things too!
>>
>> ????What such might interpret from the sample file is that the data is |
>> delimited (from the first two lines), and then fail to parse the actual
>> data lines, as there are no | delimiters -- the entire data line would be
>> treated as a single text string in column 1.
>>
>>
>> ????Given the above hypothetical understanding of the input file, I'd
>>
>> ????Manually open the input file and read the first line of the header;
>> close the file.
>> ????Split that line on | characters, and strip any remaining spaces to 
>> get
>> column labels {this won't handle the spanned columns properly -- you'd 
>> have
>> to append another label for the second "dist" column"}
>>
>>>>> h1 = "mode |?? affinity | dist from best mode"
>>>>> h1.split("|")
>> ['mode ', '?? affinity ', ' dist from best mode']
>>>>> [lbl.strip() for lbl in h1.split("|")]
>> ['mode', 'affinity', 'dist from best mode']
>> ????I would then pass that list of labels to the pandas read function 
>> while
>> telling it to skip the first three lines of the file and to not 
>> attempt to
>> parse a header. One might have to specify some other attribute to ensure
>> the data rows are parsed properly if the file is not using commas or tabs
>> to separate elements on each row.
>>
>>
>>
>>
>>
>> * Interface Control Document or Data Definition(Description) Document
>>
>>
> Thanks for you detailed thoughts. I appreciate them.
> 
> I happen to be an Organic Chemist and Computers with some of their 
> languages are among the many tools that I have used in the past 60 years 
> or so. A a gauge of my logevity, the first langauge that I managed to 
> butcher was FORTRAN II. Unfortunaly, a little bit of knowledge is a very 
> dangerous thins and last for along time.

me too :) fortunately, in my case, I appear to have kept FORTRAN II (and 
later Pascal) from polluting my mind.

> line = file[28]

Just as a general comment, Magic Numbers like 28 aren't very desirable. 
To the reader (including oneself at any time more than about two days 
later): "Wait... 28? What does that mean?". At the very least, give it a 
name.  But better is to find a pattern to look for rather than a 
specific numeric index, as that makes it more resilient to anything 
maybe not quite fitting the original model at some later time.



From PyTutor at DancesWithMice.info  Mon Dec  7 14:09:39 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Tue, 8 Dec 2020 08:09:39 +1300
Subject: [Tutor] Extract element of dtype object
In-Reply-To: <9682b9ab-9305-4444-b9ba-f6be08b72a47@wichmann.us>
References: <5FCCDE8E.1090205.ref@sbcglobal.net>
 <5FCCDE8E.1090205@sbcglobal.net>
 <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us>
 <5FCD1556.4030107@sbcglobal.net> <a4aqsf9r19ti4ohsqtld2egq4e8t4m22b2@4ax.com>
 <t8pssftck8o9h2b6sist1vee1dlvhmi3oa@4ax.com> <5FCE7010.4000805@sbcglobal.net>
 <9682b9ab-9305-4444-b9ba-f6be08b72a47@wichmann.us>
Message-ID: <3bd6d547-b31f-8d7c-fd18-31f7e1d2d4d1@DancesWithMice.info>

On 08/12/2020 07:18, Mats Wichmann wrote:
> On 12/7/20 11:10 AM, Stephen P. Molnar wrote:
>> On 12/07/2020 12:55 PM, Dennis Lee Bieber wrote:
>>> ????o/~ Talking to myself in public o/~
>>>
>>> On Sun, 06 Dec 2020 14:33:06 -0500, Dennis Lee Bieber
>>> <wlfraed at ix.netcom.com> declaimed the following:
...


>> I happen to be an Organic Chemist and Computers with some of their 
>> languages are among the many tools that I have used in the past 60 
>> years or so. A a gauge of my logevity, the first langauge that I 
>> managed to butcher was FORTRAN II. Unfortunaly, a little bit of 
>> knowledge is a very dangerous thins and last for along time.
> 
> me too :) fortunately, in my case, I appear to have kept FORTRAN II (and 
> later Pascal) from polluting my mind.

Me three!
Although far from "pollution", FORTRAN II is a constant in my  mind...


>> line = file[28]
> 
> Just as a general comment, Magic Numbers like 28 aren't very desirable. 
> To the reader (including oneself at any time more than about two days 
> later): "Wait... 28? What does that mean?". At the very least, give it a 
> name.? But better is to find a pattern to look for rather than a 
> specific numeric index, as that makes it more resilient to anything 
> maybe not quite fitting the original model at some later time.

...for example

     TARGET = 28

perfect FORTRAN, er Pascal, er Python...
-- 
Regards =dn

From maheshyayadav.1947 at gmail.com  Tue Dec  8 02:27:48 2020
From: maheshyayadav.1947 at gmail.com (KNOW NEW)
Date: Tue, 8 Dec 2020 12:57:48 +0530
Subject: [Tutor] (no subject)
Message-ID: <CACtx7Z2-EfcD=q6qQOY5FGsEFwWSRWCAVMQLOZum6QQRGp9CiA@mail.gmail.com>

Sir,
I am a student of class 11. I am learning the Python Programming and I am
trying to create a program in which I want to print "Infinite" when divisor
is 0. But when I divide by 0, it gives Infinite but also print None. Now
please advise me that what can I do to remove None and print only Infinite.
Thank you
Nikhil Yadav

From PyTutor at DancesWithMice.info  Tue Dec  8 04:56:13 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Tue, 8 Dec 2020 22:56:13 +1300
Subject: [Tutor] (no subject)
In-Reply-To: <CACtx7Z2-EfcD=q6qQOY5FGsEFwWSRWCAVMQLOZum6QQRGp9CiA@mail.gmail.com>
References: <CACtx7Z2-EfcD=q6qQOY5FGsEFwWSRWCAVMQLOZum6QQRGp9CiA@mail.gmail.com>
Message-ID: <2ec90cbf-4d09-e161-e7b9-2a089f1cba29@DancesWithMice.info>

On 08/12/2020 20:27, KNOW NEW wrote:
> Sir,
> I am a student of class 11. I am learning the Python Programming and I am
> trying to create a program in which I want to print "Infinite" when divisor
> is 0. But when I divide by 0, it gives Infinite but also print None. Now
> please advise me that what can I do to remove None and print only Infinite.
> Thank you
> Nikhil Yadav

Have you learned about Errors and Exceptions?
Wrap the division with try...except.
Look for the divide-by-zero error.
Print appropriately.
-- 
Regards =dn

From alan.gauld at yahoo.co.uk  Tue Dec  8 09:55:12 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 8 Dec 2020 14:55:12 +0000
Subject: [Tutor] (no subject)
In-Reply-To: <CACtx7Z2-EfcD=q6qQOY5FGsEFwWSRWCAVMQLOZum6QQRGp9CiA@mail.gmail.com>
References: <CACtx7Z2-EfcD=q6qQOY5FGsEFwWSRWCAVMQLOZum6QQRGp9CiA@mail.gmail.com>
Message-ID: <rqo44g$37v$1@ciao.gmane.io>

On 08/12/2020 07:27, KNOW NEW wrote:

> trying to create a program in which I want to print "Infinite" when divisor
> is 0. But when I divide by 0, it gives Infinite but also print None. 


When asking us to comment on code you should always include
the code (as plain text in your message body please)
Otherwise we are just guessing!

So making a guess I'd say you are working inside the Python
prompt and did something like this:

>>> def f(n,d):
	if d == 0:
		print( 'Infinity')
	else: return n/d

>>> print(f(5,0))
Infinity
None
>>>

You print infinity inside the function then the function
returns None(Python's default return value) and you see
both in your output. Is that right?

If so the good news is that you can avoid the None by
simply returning 'Infinity' as a string instead of printing
it inside the function.

That is also better programming practice since its better
not to mix printing and calculation inside the same function.

But, it's bad practice to return two different types(a string
and a float) so the professional way to deal with this is to
use a try/except as shown by DN.


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 alexkleider at protonmail.com  Wed Dec  9 21:30:25 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Thu, 10 Dec 2020 02:30:25 +0000
Subject: [Tutor] tarfile library question
Message-ID: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>

I have written the following code as an archiving utility to serve my needs:

import os
import shutil
import tarfile

def archive(destination_directory, source, targz_base_name):
"""
Create a <targz_base_name>.tar.gz archive and
file it in the <destination_directory>.
The archive is to contain all files &/or directories
listed in <source> (a list.)
Fails if a directory <targz_base_name> already exists.
A directory of this name is created as a temporary place to
gather what is to be archived.
"""
os.mkdir(targz_base_name)
for folder in list_of_targets:
shutil.copytree(folder,
os.path.join(targz_base_name, folder),
)
tar_file = "{}.tar.gz".format(targz_base_name)
with tarfile.open(tar_file, "w:gz") as tar:
tar.add(targz_base_name)

shutil.rmtree(targz_base_name)

res = shutil.move(tar_file, destination_directory)
if not (res == destination_directory):
print("The following two strings:")
print("\t'{}'".format(res))
print("\t'{}'".format(os.path.join(destination_directory,
tar_file)))
print("look the same to me but not to Python!! Beats me why!")

I have two questions.

1. is there a way of writing the code so as to eliminate the need to
create and populate a temporary directory and instead create the parent
directory and then populate it all within the "with...as tar" clause?
2. why are <res> and <destination_directory> not considered equal?

Thanks in advance for any light that can be shed.
Cheers,
Alex Kleider

From alan.gauld at yahoo.co.uk  Thu Dec 10 05:10:23 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 10 Dec 2020 10:10:23 +0000
Subject: [Tutor] tarfile library question
In-Reply-To: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>
References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>
Message-ID: <rqss6g$2mr$1@ciao.gmane.io>

On 10/12/2020 02:30, alexkleider via Tutor wrote:
> I have written the following code as an archiving utility to serve my needs:

You've lost the formatting so its difficult to tell where your with and
for blocks end. ie how much is inside each block...


> 
> import os
> import shutil
> import tarfile
> 
> def archive(destination_directory, source, targz_base_name):
> """
> Create a <targz_base_name>.tar.gz archive and
> file it in the <destination_directory>.
> The archive is to contain all files &/or directories
> listed in <source> (a list.)
> Fails if a directory <targz_base_name> already exists.
> A directory of this name is created as a temporary place to
> gather what is to be archived.
> """
> os.mkdir(targz_base_name)
> for folder in list_of_targets:

Where does list_of_targets come from?

> shutil.copytree(folder,
> os.path.join(targz_base_name, folder),
> )
> tar_file = "{}.tar.gz".format(targz_base_name)
> with tarfile.open(tar_file, "w:gz") as tar:
> tar.add(targz_base_name)
> 
> shutil.rmtree(targz_base_name)
> 
> res = shutil.move(tar_file, destination_directory)
> if not (res == destination_directory):
> print("The following two strings:")
> print("\t'{}'".format(res))
> print("\t'{}'".format(os.path.join(destination_directory,
> tar_file)))
> print("look the same to me but not to Python!! Beats me why!")

So what output do you get?

> 
> I have two questions.
> 
> 1. is there a way of writing the code so as to eliminate the need to
> create and populate a temporary directory and instead create the parent
> directory and then populate it all within the "with...as tar" clause?

Probably. You need a loop over the target folders somewhere
inside the open and you need to append to the tar file
not write to it.

> 2. why are <res> and <destination_directory> not considered equal?

Don't know, show us some sample output.
Also, try printing the repr() of the names as well as the str() versions.

-- 
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 alexkleider at protonmail.com  Thu Dec 10 19:12:08 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Fri, 11 Dec 2020 00:12:08 +0000
Subject: [Tutor] tarfile library question
In-Reply-To: <rqss6g$2mr$1@ciao.gmane.io>
References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>
 <rqss6g$2mr$1@ciao.gmane.io>
Message-ID: <rKEWP7Y4QB_wT_LAAA2AwrDYrlJy3haHEdmXkK4WCK2Kr0XvkIZPXtj_eSTiWGDikKIvogl23bN6Al6tGGKm58Ndoh5126adXdbabjgXPq4=@protonmail.com>

??????? Original Message ???????
On Thursday, December 10, 2020 2:10 AM, Alan Gauld via Tutor <tutor at python.org> wrote:

> On 10/12/2020 02:30, alexkleider via Tutor wrote:
>
> > I have written the following code as an archiving utility to serve my needs:
>
> >
> > 1.  is there a way of writing the code so as to eliminate the need to
> >     create and populate a temporary directory and instead create the parent
> >     directory and then populate it all within the "with...as tar" clause?
> >
>
> Probably. You need a loop over the target folders somewhere
> inside the open and you need to append to the tar file
> not write to it.
>
> > 2.  why are <res> and <destination_directory> not considered equal?
>
> Don't know, show us some sample output.
> Also, try printing the repr() of the names as well as the str() versions.
>
> --------------------------------------------------------------------------------------------------------------------
>
> Alan G

Sorry, I didn't notice that my mail client had messed up the indentation!
Here's how it should have been:

import os
import shutil
import tarfile


def archive(destination_directory, source, targz_base_name):
    """
    Create a <targz_base_name>.tar.gz archive and
    file it in the <destination_directory>.
    The archive is to contain all files &/or directories
    listed in <source> all under a directory called <targz_base_name>.
    Fails if a directory <targz_base_name> already exists.
    A directory of this name is created as a temporary place to
    gather what is to be archived.  I'd like to avoid having to do so.
    """
    os.mkdir(targz_base_name)
    for folder in list_of_targets:
        shutil.copytree(folder,
                        os.path.join(targz_base_name, folder),
                        )
    tar_file = "{}.tar.gz".format(targz_base_name)
    with tarfile.open(tar_file, "w:gz") as tar:
        tar.add(targz_base_name)

    shutil.rmtree(targz_base_name)

    res = shutil.move(tar_file, destination_directory)
    if not (repr(res) == repr(os.path.join(destination_directory,
                              tar_file))):
        print("The following two strings:")
        print("\t'{}'".format(res))
        print("\t'{}'".format(os.path.join(destination_directory,
                            tar_file)))
        print("...should be the same: something went wrong!")

The second of my questions has been resolved (silly bug of my doing!)
The first question remains:
   How to avoid having to create the temporary directory targz_base_name
presumably by setting it up within the "while tarfile(... as tar:" loop.

Sorry about the confusion and thanks again in advance for any suggestions.
Alex Kleider



From alan.gauld at yahoo.co.uk  Fri Dec 11 04:36:36 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 11 Dec 2020 09:36:36 +0000
Subject: [Tutor] tarfile library question
In-Reply-To: <rKEWP7Y4QB_wT_LAAA2AwrDYrlJy3haHEdmXkK4WCK2Kr0XvkIZPXtj_eSTiWGDikKIvogl23bN6Al6tGGKm58Ndoh5126adXdbabjgXPq4=@protonmail.com>
References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>
 <rqss6g$2mr$1@ciao.gmane.io>
 <rKEWP7Y4QB_wT_LAAA2AwrDYrlJy3haHEdmXkK4WCK2Kr0XvkIZPXtj_eSTiWGDikKIvogl23bN6Al6tGGKm58Ndoh5126adXdbabjgXPq4=@protonmail.com>
Message-ID: <rqvej4$rr1$1@ciao.gmane.io>

On 11/12/2020 00:12, alexkleider via Tutor wrote:

>> Probably. You need a loop over the target folders somewhere
>> inside the open


> def archive(destination_directory, source, targz_base_name):

     with .... as tar:

>        for folder in list_of_targets:

            tar.add(folder)

>    res = shutil.move(tar_file, destination_directory)
>    if not (repr(res) == repr(os.path.join(destination_directory,
>         print("...should be the same: something went wrong!")

Should work?

You still don't tell us where list_of_targets comes from?
It's not in the function so presumably is a global, which
is not a good idea... Or is it a typo and it should
be the "source" parameter?

-- 
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 alexkleider at protonmail.com  Fri Dec 11 09:55:19 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Fri, 11 Dec 2020 14:55:19 +0000
Subject: [Tutor] tarfile library question
In-Reply-To: <rqvej4$rr1$1@ciao.gmane.io>
References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com>
 <rqss6g$2mr$1@ciao.gmane.io>
 <rKEWP7Y4QB_wT_LAAA2AwrDYrlJy3haHEdmXkK4WCK2Kr0XvkIZPXtj_eSTiWGDikKIvogl23bN6Al6tGGKm58Ndoh5126adXdbabjgXPq4=@protonmail.com>
 <rqvej4$rr1$1@ciao.gmane.io>
Message-ID: <j9pk-DZ5jRP-aKhFCmZ3XM4MYtR1Qgm-53kiut13neEtcNkHdl3PIkUuuFIC-2opfEg4vPdgtx3onO1ARnDt9U7uXWFEUMbzsojec8NNuGA=@protonmail.com>

??????? Original Message ???????
On Friday, December 11, 2020 1:36 AM, Alan Gauld via Tutor <tutor at python.org> wrote:

> On 11/12/2020 00:12, alexkleider via Tutor wrote:
>
> > > Probably. You need a loop over the target folders somewhere
> > > inside the open
>
> > def archive(destination_directory, source, targz_base_name):
>
> with .... as tar:
>
> >        for folder in list_of_targets:
> >
>
> tar.add(folder)
>
> > res = shutil.move(tar_file, destination_directory)
> > if not (repr(res) == repr(os.path.join(destination_directory,
> > print("...should be the same: something went wrong!")
>
> Should work?
>
> You still don't tell us where list_of_targets comes from?
> It's not in the function so presumably is a global, which
> is not a good idea... Or is it a typo and it should
> be the "source" parameter?
>

Oops!
Yes, it should have been "source" (which needs to be a list of target directories &/or files.)
Apologies again.
a

From nathan-tech at hotmail.com  Tue Dec 15 14:11:21 2020
From: nathan-tech at hotmail.com (nathan tech)
Date: Tue, 15 Dec 2020 19:11:21 +0000
Subject: [Tutor] I don't quite understand bitwise
Message-ID: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>

Hi mailing list,


So I'm working on a project that, as part of this project has a function 
called self.RegisterHotKey9arg1, arg2, arg3)

It's wx python for context, but I don't think that is relevant.

An example of this is:

self.RegisterHotKey(self.kid6, win32con.MOD_ALT|win32con.MOD_SHIFT, 0x46)


What I wanted to do was make it so that the second argument could be 
anything. I was sort of treating arg2 as a list, and so I'd do something 
like:

l=["shift","windows","alt"]

bit=None

for x in l:

 ?bit=bit+x+|


So I started to research how the x|y format works and came across 
bitwise operators which is apparrently what is meant when x|y|z is used.

But to me they look like ints/

I am just... Completely lost on how this eeven works.


Thanks in advance.

Nathan (the lost python)


From steve at alchemy.com  Tue Dec 15 16:39:28 2020
From: steve at alchemy.com (Steve Willoughby)
Date: Tue, 15 Dec 2020 13:39:28 -0800
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
Message-ID: <f535e0cd3735f2854f13f91ecd25cac7432f27d2.camel@alchemy.com>

On Tue, 2020-12-15 at 19:11 +0000, nathan tech wrote:
> So I started to research how the x|y format works and came across 
> bitwise operators which is apparrently what is meant when x|y|z is
> used.
> 
> But to me they look like ints/

Yes, they are, in fact, ints. The bitwise-OR (|) is a math operator
that acts on two integer values.

Say x = 0b1010 and y = 0b1100.
If you go bit-by-bit and apply the OR operation on the corresponding
bits of x and y, you get:

x   1010
y   1100
x|y 1110

so in python the result of x|y is 0b1110, or 14 in decimal.

This kind of thing has a long history in C and other languages for
specifying a set of options as a single integer parameter to a
function.

So if, say, you could have any combination of OPTA, OPTB, and OPTC as
"flags" to pass to a function, you could assign

OPTA = 0b001
OPTB = 0b010
OPTC = 0b100

and you could pass the parameter as 0, OPTA, OPTB|OPTC, OPTA|OPTC, etc.
Respectively that would be the values 0, 0b001, 0b011, 0b101, etc. as
the called function would see them.

From cs at cskk.id.au  Tue Dec 15 16:59:17 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Wed, 16 Dec 2020 08:59:17 +1100
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
Message-ID: <20201215215917.GA89219@cskk.homeip.net>

On 15Dec2020 19:11, nathan tech <nathan-tech at hotmail.com> wrote:
>So I'm working on a project that, as part of this project has a 
>function called self.RegisterHotKey9arg1, arg2, arg3)
>
>It's wx python for context, but I don't think that is relevant.
>
>An example of this is:
>self.RegisterHotKey(self.kid6, win32con.MOD_ALT|win32con.MOD_SHIFT, 0x46)
>
>What I wanted to do was make it so that the second argument could be 
>anything. I was sort of treating arg2 as a list, and so I'd do 
>something like:
>
>l=["shift","windows","alt"]
>
>bit=None
>for x in l:
>?bit=bit+x+|
>
>So I started to research how the x|y format works and came across 
>bitwise operators which is apparrently what is meant when x|y|z is 
>used.

Yes.

>But to me they look like ints/

They are ints.

So, we normally write integers in base 10, since we're raised learning 
arithmetic that way and the Arabic number system uses 10 digits. So the 
int 13 is the sum of 1*10 +3.

But we store integers in computers in base 2 because the basic storage 
unit (a "bit") can hold one of 2 values. So in base 2 the value 13 it 
composed of 1*8 + 1*4 + 0*2 + 1*1, and is written 1101 (or 0b1101 if 
you're putting that in a Python programme).

So, bitmasks.

Instead if treating a bitmask as something we do arithmetic with, we 
treat a bitmask as a sequence of independent bits, each indicating an 
on/off or true/false status. We aren't _using_ them as "int"s/numbers, 
we're using them as an array of 1/0 values.

They're just _stored_ in an int.

So your RegisterHotKey call has arg2 as 
win32con.MOD_ALT|win32con.MOD_SHIFT is composing such an array. I don't 
know the values of win32con.MOD_ALT etc, but each will normally be some 
power of 2. Supposing we had these powers of 2 named:

    win32con.MOD_ALT     = 0b1000  # an 8
    win32con.MOD_CTRL    = 0b0100  # a 4
    win32con.MOD_FN      = 0b0010  # a 2
    win32con.MOD_SHIFT   = 0b0001  # a 1

The expression win32con.MOD_ALT|win32con.MOD_SHIFT is 0b1000|0b0001.  
Which is 0b1001 - you're just setting particular bits within the value.

Doing another |win32con.MOD_SHIFT just sets 0b0001 again, which changes 
nothing - it is already a 1.

The "|" is pronounced "or" (well, "bitwise or"). And "&" is pronounced 
"and" (well, "bitwise and"). The result of a|b is a 1 if a=1 or b=1. The 
result of a&b is 1 if a=1 and b=1. Each bit is treated independently.

So pretending the values above, win32con.MOD_ALT|win32con.MOD_SHIFT is 
0b1001, which happens to b a 9 if you treat it as a number.

Doing things this way is effectively a compact way of passing around 
combinations of true/false states, something you _might_ do verbosely in 
Python like this:

    RegisterHotKey(self.kid6, mod_alt=True, mod_shift=True, ...)

but it isn't written that way. The underlying reaons are twofold:

- who wants to write "mod_alt=True, mod_shift=True, ..." for this stuff?

- the underlying library will likely be a C or C++ library, and it is 
  routine to collect "flags" (true/false values) together in a bitmask 
  and just pass it around as an int.

Happy to elaborate further if anything is unclear.

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

From PyTutor at DancesWithMice.info  Tue Dec 15 17:29:52 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Wed, 16 Dec 2020 11:29:52 +1300
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
Message-ID: <87fdd97b-3038-016d-c787-5817714cfac6@DancesWithMice.info>

On 16/12/2020 08:11, nathan tech wrote:
...

> An example of this is:
> self.RegisterHotKey(self.kid6, win32con.MOD_ALT|win32con.MOD_SHIFT, 0x46)
> 
...

> So I started to research how the x|y format works and came across 
> bitwise operators which is apparrently what is meant when x|y|z is used.
> 
> But to me they look like ints/
> 
> I am just... Completely lost on how this eeven works.


You are correct in saying that they look like ints. However, the next 
question is to ask, 'what do ints look like?'

Aside: At $work we are very concerned by, and often debate, the options 
of learning Python on its own, eg the 'boot camp' idea (no one who has 
suffered a military Boot Camp would ever put the two in the same 
category!). The comparisons come down to the time it takes to complete a 
traditional degree program[me] and its (crushing!) costs; versus the 
thinness of depth and narrowness of coverage that characterises a 
'fast-course'. Perhaps a separate "Friday Finking" discussion...

Apparently you have learned Python, perhaps even taught yourself, 
without the traditional backing of a ComSc degree. For which I praise 
you, and any implied-criticism is for the approach.

In a 'full-fat' ComSc course there would be coverage of 
computer-hardware and how it works, including the use of binary code and 
boolean algebra; and perhaps even some exposure to machine code and/or 
assembler languages. All of which gives (me at least) a great 
appreciation for Python, its idea of a "virtual machine", and how it 
saves us from so much 'pain'!

So, after all that mumbling-and-grumbling, here's a short-version (with 
the assumption that you'll read-up about the parts you don't 
already/immediately understand):-


We talk about using a "64-bit computer" (or perhaps a slightly older 
machine might be 32-bit). What is a "bit"? We used to think of a 
"binary-digit" as the smallest unit of information in a computer. The 
analog was a light-switch, which can either turn the lamp "on" or "off".

However, computer-storage is usually "addressed" at the level of 
"bytes". What is a byte? Eight bits! Just as a bit can only assume one 
of only two possible "states", a byte has exactly 2? unique states, ie 
256. [in case it doesn't come-through the email, that's two superscript 
8, ie two to the eighth power] "Two" is quite a small number, and 256 is 
still not very large. So, bytes are often grouped-together for strength.

Back to our computer's 'size', those "64-bits" could also be considered 
a collection of eight bytes! In the ?good, old, days we might have 
referred to this grouping of bits/bytes as a "word".

At this point we could 'disappear' into computer architecture, but 
Python's interpreter abstracts us away from such detail. Let's spare 
ourselves and move-on.


If we have a series of bits (or bytes), some of which are turned 'on' 
and some of which are 'off', eg

     0110 0001

what does this mean? The opaque answer is that it can mean anything that 
you want it to mean! For example, you mentioned ints. This succession of 
bits could be said to mean the integer "97" (and it does!).

What about learning our (Latin) alphabet? These (same) bits could 
represent the letter "a" (again, it does!).

How about if we have a set called "fruit"? The first four bits (I'm too 
lazy to do more*) could indicate that we have some combination of an 
apple, a banana, a clementine, a durian... in which case:

     0110 ~ a banana and a clementine

So, it's all about "encoding"! Thus, how do we use the binary-digits 
and/or what do they represent. Until you apply *your* meaning to the 
bits, we can't be more specific amongst the choices:

     0110 0001 ~ 97 ~ "a" ~ a banana and a clementine (etc)


Let's 'cheat' for a moment, and stay with my abbreviated four-element 
sets of fruit.

Cast your mind back to the school-yard. Perhaps your Mum/Mom gave you 
some food to eat at school, and perhaps mine also for me. Being kids we 
always thought that what the other had was somehow better than our own. 
So, being clever, little, nascent-coder, problem-solvers, we would 
compare and contrast before making deals to trade/swap.

Let's say I turn-up with a a banana and a clementine, and you've been 
given a durian. As a first step, lets add or 'pool' them together. Now 
we have a pile (set) of fruit consisting of a banana, a clementine, and 
a durian. With that knowledge we can start 'trading', and because you're 
bigger (stronger, and can leap more buildings at a single bound) than 
me, you take the lot - throwing-down the banana peal for me to slip on 
(no, you wouldn't do that to me. Would you?)

Let's use the same system as above to represent the two sets of fruit, 
and what happens when we create a 'pool':

     mine:     { banana, clementine }
     yours:    { durian }
     the pool: { banana, clementine, durian }

Applying the 'encoding' method, this could be expressed, in bits, as:

     mine:     0110
     yours:    0001
     the pool: 0111

Are we agreed that 0110? represents or 'equals' a banana, a clementine, 
and a durian?
(in case it doesn't come-through the email, that's 0110 subscript two, 
ie 0110 in base-2)

Did you notice the columnar relationship? If there is a 1 from either 
(or both) rows, then the column position representing the pool will be 
one. If neither is one (or both 'mine' and 'yours' is zero) then the 
pool's column or bit will be zero!

Thus, taking the calculation one bit at a time ("bit-wise"!), if 'my' 
bit is one *or* 'your' bit is one, then the answer-bit is set to one. 
Conversely, if neither bit is one, then the answer-bit is set to zero.

This is the binary OR operation!
NB there are variants, but they're irrelevant to the stated application. 
(fortunately!)


Finally, we reach 'the point'!

In the (above) explanation, combining the two sets was referred to as 
"adding" or "pooling". In Boolean Algebra, bitwise 'adding' is called 
"or", ie if either you *or* I had a piece of that type of fruit to 
contribute to the pool, it would appear in the pool.

NB The analogy breaks-down if we both contribute an apple, because sets 
don't 'count' how many of each item. To account for that, we need to 
represent our 'pool' using integers (unless I've already eaten part of 
my apple on the way to school - not an unheard-of event! Now, we're 
talking "floats" or "real numbers" and we're not going there...) ie 
different encoding systems!

In the wxPython context, we are discussing modifier-keys, of which there 
is a finite set, and there's no such thing as two 'flag'/'Windows' keys 
(and the two shift-keys can be separately-identified). Accordingly, a 
key-combination is a set, a pooling, of multiple keys; which presumably 
will lead to a particular choice/function.

So, whilst the wxPython-people are content to use Boolean Algebra and 
bitwise-or functions to express a key-combination; apparently you would 
prefer a 'higher-level abstraction'. Hey, I'm with you on this!

Perhaps then use a Python set rather than a list, and you'll be off 
laughing.
(and with a belly full of good, healthy, fruit - but if you're going to 
cut-open that durian, I'm heading a long way away, up-wind!)


* and yes, just to leave anyone who has read this far with a smile, 
those four bits (half a byte) could be referred to as a "nibble" or 
"nybble". Actually, this not just a joke. The first single-chip CPUs 
were four-bit computers. These are still available, and applied in 
numerous situations.

Furthermore, it seems likely that the use (and understanding) of 
Python's bit-wise operations will become more important with the 
increasing use of Raspberry Pi-s and other SBCs, MicroPython, etc!
-- 
Regards =dn

From alan.gauld at yahoo.co.uk  Tue Dec 15 19:08:41 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 16 Dec 2020 00:08:41 +0000
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
Message-ID: <rrbj6a$qkh$1@ciao.gmane.io>

On 15/12/2020 19:11, nathan tech wrote:

> So I started to research how the x|y format works and came across 
> bitwise operators which is apparrently what is meant when x|y|z is used.

You can find a discription of nitwide operators and their use in
programming in the Functional Programming topic in my tutorial.

However long story short is:

if you do A|B

then any bit that is 1 in either A or B will be 1 in the output.

if you do A&B

then any bit that is 0 in either A or B will be 0 in the output.

Thus A|B combines the 1s in both entities - this is usually
what you want when the entities represent sets of options
such as application options and user defined options.

So if you want the total number of options set you can do

options_var = user|application
# now use the combined options_var

And A&B can be used to select a subset of options by making B
a "mask" - that is a known bit pattern.

Thus if you want to know if bits 2 and 4 of A are set to 1 do this:

B = 0b1010
res = A&B
if res == B: print("Both options are set")
else: print("One, or both, options are not set")

Finally, | can be used to accumulate results over several
operations. You used to see this before try/except
style error handling became common:

errors = 0
errors |= operation1(myObject)
errors |= operation2(myObject)
errors |= operation3(myObject)
errors |= operation4(myObject)
if errors:
   # something went wrong, deal with it!
else:
   #  All OK so now use myObject

A |= B is f course the same as
A = A|B

And if all operations return zero on success then any
other result will have some 1s in it, and these will
be transferred to errors.

For bonus points the last place you might see bitwise
operations is in cryptography.
There the exclusive OR operator is used to encode data
in such a way that it can be recovered later by applying
the same mask

#At transmitter
key = 42
data = "some string here"
cipher = ''.join(ch^key for ch in data)
print (cipher) # garbage...

# transmit cipher...

# at receiver:
key = 42   # same as transmitter
message = receiveData()
plain_text = ''.join(ch|key for ch in message)
print(plain_text)  # prints "some string here"

Of course that easy to crack but many real world cipher
systems are based on layers of algorithms on top of
a similar basic concept.

To conclude, the reason all this works is because of
the definitions of the operations as described by
their truth tables:

A	B	A|B	A&B	A^B
0	0	0	0	0
0	1	1	0	1
1	0	1	0	1
1	1	1	1	0

So
A|B is 1 when any of A or B is 1
A&B is only 1 if both  A and B are 1
A^B(exclusive or) is 1 if A and B are different.


Try them in the >>> prompt, see if you can predict the results before
hitting return:

>>> A = 0b1010
>>> B = 0b1100
>>> bin(A|B)
????
>>> bin(A&B)
????
>>> bin(A^B)
????

-- 
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 nathan-tech at hotmail.com  Wed Dec 16 13:48:18 2020
From: nathan-tech at hotmail.com (nathan tech)
Date: Wed, 16 Dec 2020 18:48:18 +0000
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <rrbj6a$qkh$1@ciao.gmane.io>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
 <rrbj6a$qkh$1@ciao.gmane.io>
Message-ID: <DB7PR07MB50935F2F5D88FD0D968E4C47E4C50@DB7PR07MB5093.eurprd07.prod.outlook.com>

Hello

Just wanted to give a quick thanks for everyone's responses.

I will be reviewing your answers in the next few days and will ask more 
if I need :)

Nathan

On 16/12/2020 00:08, Alan Gauld via Tutor wrote:
> On 15/12/2020 19:11, nathan tech wrote:
>
>> So I started to research how the x|y format works and came across
>> bitwise operators which is apparrently what is meant when x|y|z is used.
> You can find a discription of nitwide operators and their use in
> programming in the Functional Programming topic in my tutorial.
>
> However long story short is:
>
> if you do A|B
>
> then any bit that is 1 in either A or B will be 1 in the output.
>
> if you do A&B
>
> then any bit that is 0 in either A or B will be 0 in the output.
>
> Thus A|B combines the 1s in both entities - this is usually
> what you want when the entities represent sets of options
> such as application options and user defined options.
>
> So if you want the total number of options set you can do
>
> options_var = user|application
> # now use the combined options_var
>
> And A&B can be used to select a subset of options by making B
> a "mask" - that is a known bit pattern.
>
> Thus if you want to know if bits 2 and 4 of A are set to 1 do this:
>
> B = 0b1010
> res = A&B
> if res == B: print("Both options are set")
> else: print("One, or both, options are not set")
>
> Finally, | can be used to accumulate results over several
> operations. You used to see this before try/except
> style error handling became common:
>
> errors = 0
> errors |= operation1(myObject)
> errors |= operation2(myObject)
> errors |= operation3(myObject)
> errors |= operation4(myObject)
> if errors:
>     # something went wrong, deal with it!
> else:
>     #  All OK so now use myObject
>
> A |= B is f course the same as
> A = A|B
>
> And if all operations return zero on success then any
> other result will have some 1s in it, and these will
> be transferred to errors.
>
> For bonus points the last place you might see bitwise
> operations is in cryptography.
> There the exclusive OR operator is used to encode data
> in such a way that it can be recovered later by applying
> the same mask
>
> #At transmitter
> key = 42
> data = "some string here"
> cipher = ''.join(ch^key for ch in data)
> print (cipher) # garbage...
>
> # transmit cipher...
>
> # at receiver:
> key = 42   # same as transmitter
> message = receiveData()
> plain_text = ''.join(ch|key for ch in message)
> print(plain_text)  # prints "some string here"
>
> Of course that easy to crack but many real world cipher
> systems are based on layers of algorithms on top of
> a similar basic concept.
>
> To conclude, the reason all this works is because of
> the definitions of the operations as described by
> their truth tables:
>
> A	B	A|B	A&B	A^B
> 0	0	0	0	0
> 0	1	1	0	1
> 1	0	1	0	1
> 1	1	1	1	0
>
> So
> A|B is 1 when any of A or B is 1
> A&B is only 1 if both  A and B are 1
> A^B(exclusive or) is 1 if A and B are different.
>
>
> Try them in the >>> prompt, see if you can predict the results before
> hitting return:
>
>>>> A = 0b1010
>>>> B = 0b1100
>>>> bin(A|B)
> ????
>>>> bin(A&B)
> ????
>>>> bin(A^B)
> ????
>

From alan.gauld at yahoo.co.uk  Wed Dec 16 17:00:28 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 16 Dec 2020 22:00:28 +0000
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <rrbj6a$qkh$1@ciao.gmane.io>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
 <rrbj6a$qkh$1@ciao.gmane.io>
Message-ID: <rre01s$mdu$1@ciao.gmane.io>

On 16/12/2020 00:08, Alan Gauld via Tutor wrote:

> You can find a discription of nitwide operators 

Ahem, nitwide should of course be bitwise!

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



From PyTutor at DancesWithMice.info  Wed Dec 16 17:50:02 2020
From: PyTutor at DancesWithMice.info (dn)
Date: Thu, 17 Dec 2020 11:50:02 +1300
Subject: [Tutor] I don't quite understand bitwise
In-Reply-To: <rre01s$mdu$1@ciao.gmane.io>
References: <DB7PR07MB5093A3A23FDC11ED6641F029E4C60@DB7PR07MB5093.eurprd07.prod.outlook.com>
 <rrbj6a$qkh$1@ciao.gmane.io> <rre01s$mdu$1@ciao.gmane.io>
Message-ID: <a8990bab-7d92-9485-0777-8ecc7f1980a0@DancesWithMice.info>

On 17/12/2020 11:00, Alan Gauld via Tutor wrote:
> On 16/12/2020 00:08, Alan Gauld via Tutor wrote:
> 
>> You can find a discription of nitwide operators
> 
> Ahem, nitwide should of course be bitwise!
> 
> Oops,


Worked for me - wouldn't a person 'good' at nit-picking, likely also 
find bit-picking easy?
-- 
Regards =dn

From sahuprashant200101 at gmail.com  Mon Dec 21 00:40:11 2020
From: sahuprashant200101 at gmail.com (prashant sahu)
Date: Mon, 21 Dec 2020 11:10:11 +0530
Subject: [Tutor] Trouble at running
Message-ID: <CAM8v0-VhHL3LtPAgzQu3ECPxz-nKvNqDx8mZ5GPmer_VqCKD2g@mail.gmail.com>

Sir I am a very new kind of beginner at python. I tried to execute my first
hello world program via python 3.9.0  but the running window just opens for
a half second and disappears,, sir what I have to modify here to keep the
window opened for a long,,
My program is:
print ("hello world")
Than I saved it with _.py type
Thank you sir

From alan.gauld at yahoo.co.uk  Mon Dec 21 05:33:31 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 21 Dec 2020 10:33:31 +0000
Subject: [Tutor] Trouble at running
In-Reply-To: <CAM8v0-VhHL3LtPAgzQu3ECPxz-nKvNqDx8mZ5GPmer_VqCKD2g@mail.gmail.com>
References: <CAM8v0-VhHL3LtPAgzQu3ECPxz-nKvNqDx8mZ5GPmer_VqCKD2g@mail.gmail.com>
Message-ID: <rrptlr$13gd$1@ciao.gmane.io>

On 21/12/2020 05:40, prashant sahu wrote:
> Sir I am a very new kind of beginner at python. I tried to execute my first
> hello world program via python 3.9.0  but the running window just opens for
> a half second and disappears,, sir what I have to modify here to keep the
> window opened for a long,,
> My program is:
> print ("hello world")

There are several ways to deal with this, the most common are:

1) Run your program from a command shell. You don't say which OS you use
but if its Linux you'll know about shells, if its MacOS I think you use
the Terminal application in the Utilities folder, and if it's Windoze use
WindowsKey-R and type in CMD.EXE.
Then when the shell window appears, at the OS prompt type

python path\to\your\python\file

This is probably the best option when developing programs since it will
show you any errors as well as the output when the code works properly.

2) Add a line like:

input("Hit enter to exit")

at the very end of your program file.
This like will print the message and then wait for the user to
type something. This is how you will normally deal with this problem
in working programs. The disadvantage is that if your code has an
error in it then you will never reach this line and the console
will still disappear. Revert to method 1 in that case.

Either that or use a tool like IDLE to develop your code since
IDLE will trap the error for you.

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



From wilbur6453 at gmail.com  Mon Dec 21 17:48:24 2020
From: wilbur6453 at gmail.com (Mike Wilbur)
Date: Mon, 21 Dec 2020 17:48:24 -0500
Subject: [Tutor] Python Regex re.search() to parse system logs
Message-ID: <CAF41aGH5iNjh-m8mPGmDJ4pzQOOU-irGigYu2CxNaaZRiDkn6w@mail.gmail.com>

I am beginning to learn python regex.  I was presented with the following
problem:

*Given:*
import re
def show_time_of_pid(line):
  pattern = ___  # need to complete regex code to support desired output
  result = re.search(pattern, line)
  return ___  # need to complete for desired output

print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER
(good_user)")) # call to run function with parameter
# Desired output per below:
# Jul 6 14:01:23 pid:29440

My code so far keeps pulling in the string "computer.name CRON[".  I can
get the date & time OR the pid #.  But not by themselves.  I have not
looked at adding the "pid:" to the output yet.

*My code:*
print(re.search("(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})", "Jul 6 14:01:23
computer.name CRON[29440]: USER (good_user)"))
<re.Match object; span=(0, 39), match='Jul 6 14:01:23 computer.name
CRON[29440'>

Produced code using group names that isolates desired output.  But this
will not work with re.search() I believe.  I think I'd need to use re.sub()
instead.


*print(re.search("(?P<timestamp>[\w
\:]{15}).*[^a-zCRON].*\[(?P<pid>[\d]{5})\]", "Jul 6 14:01:23 computer.name
<http://computer.name> CRON[29440]: USER (good_user)"))<re.Match object;
span=(0, 40), match='Jul 6 14:01:23 computer.name <http://computer.name>
CRON[29440]'>*

[image: image.png]


I know I am missing something straight forward.  I've been unsuccessful
using google or stackoverflow to find what I am missing.

Any suggestions would be greatly appreciated.

Best, Mike

From cs at cskk.id.au  Tue Dec 22 01:06:06 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Tue, 22 Dec 2020 17:06:06 +1100
Subject: [Tutor] Python Regex re.search() to parse system logs
In-Reply-To: <CAF41aGH5iNjh-m8mPGmDJ4pzQOOU-irGigYu2CxNaaZRiDkn6w@mail.gmail.com>
References: <CAF41aGH5iNjh-m8mPGmDJ4pzQOOU-irGigYu2CxNaaZRiDkn6w@mail.gmail.com>
Message-ID: <20201222060606.GA23693@cskk.homeip.net>

Comments below...

On 21Dec2020 17:48, Mike Wilbur <wilbur6453 at gmail.com> wrote:
>print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER
>(good_user)")) # call to run function with parameter
># Desired output per below:
># Jul 6 14:01:23 pid:29440
>
>My code so far keeps pulling in the string "computer.name CRON[".  I can
>get the date & time OR the pid #.  But not by themselves.  I have not
>looked at adding the "pid:" to the output yet.
>
>*My code:*
>print(re.search("(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})", "Jul 6 14:01:23
>computer.name CRON[29440]: USER (good_user)"))

A recommendation: use "raw strings" when writing regexps:

   r"(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})"

or:

   r'(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})'

That leading "r" marks this as a "raw string", which means in particular 
that backslahses are not special to Python. Since regexps use 
backslashes to represent character classes and other things, using a raw 
string prevents Python's own backslash stuff from getting in the way.  
You will have fewer accidents this way.

><re.Match object; span=(0, 39), match='Jul 6 14:01:23 computer.name
>CRON[29440'>
>
>Produced code using group names that isolates desired output.  But this
>will not work with re.search() I believe.

It works just find with re.search. re.match and re.search both return 
"Match" objects, they just differ in where they start in the text.

>I think I'd need to use re.sub() instead.

No need.

Let's look at your regexp (ignoring the quotes - they're just for 
Python):

   (^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})

Brackets () in a regexp group a section as a single unit. You don't need 
brackets around the whole thing.

   ^[\w \:]{15}.*[^a-z\.CRON][0-9]{5}

Let's look at each part:

^           Start of string.

[\w \:]     A single character which is a "word" character or a space or
            a colon.

{15}        Exactly 15 such characters.

.*          Any number of characters (zero or more of '.', which is any
            single character).

[^a-z\.CRON] A single character which is not one of a-z, ., C, R, O, N.

[0-9]       A digit. Which can also be written \d
{5}         Exactly 5 such characters, so exactly 5 digits.

I think your "CRON" above should be _outside_ the [] character range.

I recommend starting with a sample input line and deciding how to match 
each piece alone. You often have a choice here - take the simplest 
choice available.

So:

    Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)

Your "[\w :]{15}" looks good. Dates in these logs are a fixed length and 
this will be reliable.

After that I tend to be less believing. So I'd match the spaces with 
\s+, meaning "1 or more space characters".

A computer name may have several characters, but won't have whitespace.  
You know where it will be, so just match \S+, meaning "1 or more 
nonspace characters".

"CRON" seems critical to you. You can match it literally just by writine 
CRON.

Alternatively, you might want any service, not just cron, so you could 
match a word ending in digits in brackets. Eg \S+\[\d+\] meaning "one or 
more nonspace characters followed by a left square bracket followed by 1 
or more digits followed by a right square bracket".

And so on.

You do not need to match the entire line. Just stop!

This lets you build up your regular expression progressively. Match the 
first thing. When that's good, add some more pattern and test again.  
Continue until you have matched everything that you need.

Your plan to use named section is good: surround the important pieces in

    (?<name>

and

    )

Then the match object will have these names pieces for use by name 
later. See the Match.groupdict method. Example:

    ptn = re,compile(r'your regexp in here')
    m = ptn.match(your_input_line_here)
    if not m:
        print("NO MATCH")
    else:
        matches = m.groupdict()
        # print the timestamp part of your match
        print(matches['timestamp'])

So start slowly: write a regexp, with named parts, that just matches the 
first thing. And print it by name as above. Then extend the expression 
one part at a time until everything matches.

That way you only need to consider problems with the small thing you 
have added.

Finally, note that most regexp patterns are "greedy". So .* will match 
zero or more. But as many as possible.

You might be concerned that that would match the entire line of text.  
Well it would, _except_ that it will only match stuff as long as the 
rest of the pattern _also_ matches. So if using the whole line prevents 
the rest of the pattern matching, it backs off a character and tries 
again, making it shorter and shorter until the rest of the pattern does 
match.

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

From david at graniteweb.com  Tue Dec 22 11:46:25 2020
From: david at graniteweb.com (David Rock)
Date: Tue, 22 Dec 2020 10:46:25 -0600
Subject: [Tutor] String slicing off the end question
Message-ID: <20201222164625.GZ5746@apple.graniteweb.com>

I was just doing some string slicing, and came across a behavior I did not expect.

>>> somestring = 'python'

>>> somestring[:2]
'py'

>>> somestring[:10]
'python'

In particular, I was surprised by defining a slice outside the range not
throwing an exception (eg, in the example above, the string is length 6,
but setting a stop of 10 doesn't have any issues and appears to just
return the whole string).  Is this how it's supposed to work? If it is,
then why?  Is this behavior reliable?

Thanks. 

-- 
David Rock
david at graniteweb.com

From alan.gauld at yahoo.co.uk  Tue Dec 22 12:28:47 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 22 Dec 2020 17:28:47 +0000
Subject: [Tutor] String slicing off the end question
In-Reply-To: <20201222164625.GZ5746@apple.graniteweb.com>
References: <20201222164625.GZ5746@apple.graniteweb.com>
Message-ID: <rrtacf$ii0$1@ciao.gmane.io>

On 22/12/2020 16:46, David Rock wrote:

>>>> somestring[:10]
> 'python'
> 
> In particular, I was surprised by defining a slice outside the range not
> throwing an exception (eg, in the example above, the string is length 6,
> but setting a stop of 10 doesn't have any issues and appears to just
> return the whole string).  Is this how it's supposed to work? If it is,
> then why?  Is this behavior reliable?

Yes, it's how its defined in the language reference. I couldn't find
the actual reference but the tutorial (Sect 3.1.2) does include
this comment when discussing slicing:

######################
Attempting to use an index that is too large will result in an error:
>>>

>>> word[42]  # the word only has 6 characters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range

However, out of range slice indexes are handled gracefully when used for
slicing:
>>>

>>> word[4:42]
'on'
>>> word[42:]
''

#######################

So an out of bounds *index* is an error but an out of bounds slice
marker degrades "gracefully".

-- 
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 bobtrooper.games at gmail.com  Thu Dec 24 00:48:01 2020
From: bobtrooper.games at gmail.com (GardeGlory)
Date: Thu, 24 Dec 2020 00:48:01 -0500
Subject: [Tutor] Command Lines
Message-ID: <CAGBm6oF2USoOHrXE4fPGcTtQ-FwGy_Cs2rYcVaeBi8cHxD25Ew@mail.gmail.com>

Hey y'all! I hope you and your teams are doing well this Christmas season.I
know that this is by far not the preferred method of communication or help
for this type of problem, but I am mentally exhausted from countless hours
of forum searching and youtube videos... The reason I am reaching out is
that I am new to the Python scene and am trying to set up a basic web
scraping script, however, I ran into a "pip install" problem, so, after
hours of scrounging around trying to figure out what a "command line" is,
can you guys give me a step-by-step to try and dumb it down for me? What is
a command line? And how do I go from it to doing something like "pip
install requests"? Any help would be great, thank you so much, GardeGlory.

From alan.gauld at yahoo.co.uk  Thu Dec 24 05:36:44 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 24 Dec 2020 10:36:44 +0000
Subject: [Tutor] Command Lines
In-Reply-To: <CAGBm6oF2USoOHrXE4fPGcTtQ-FwGy_Cs2rYcVaeBi8cHxD25Ew@mail.gmail.com>
References: <CAGBm6oF2USoOHrXE4fPGcTtQ-FwGy_Cs2rYcVaeBi8cHxD25Ew@mail.gmail.com>
Message-ID: <rs1qvu$c7u$1@ciao.gmane.io>

On 24/12/2020 05:48, GardeGlory wrote:

> scraping script, however, I ran into a "pip install" problem, so, after
> hours of scrounging around trying to figure out what a "command line" is,
> can you guys give me a step-by-step to try and dumb it down for me? What is
> a command line? And how do I go from it to doing something like "pip


A command line is a prompt at which you type commands.
Exactly how you do that depends on your Operating System.
- On Linux for example I type Ctrl-Alt-T and a new Terminal
  window appears with a Bash command line.
- On Windoze I type Windows-R to get the run dialog then
  type CMD into that and hit OK to get a new CMD prompt window.
- On a Mac I have a shortcut to the Terminal application on the dock.
- On Android I have a shell app installed that I run in the usual
  manner to get a bash prompt there.

Once you have that prompt you can type commands such as
(Linux): ls, cd,  clear, mv etc...
(Windows): DIR, CD, CLS, RENAME, etc...
(Mac): same as Linux!
(Android): same as Linux:

What the prompt looks like depends on your user settings.
You can configire it as you like. The default prompt in
Windows is usually something like:

C:\WINDOWS>

ie a folder path followed by a >

In Unix based systems it is normally set up to be your
user name followed by the current folder path and possibly
the current command number (starting at 1 for each new session)
And finally a $ sign. If you are loggedin as the superuser
the $ will become a #. Thats important when following web
tutorials since if they show the # it means you need to be
logged in as superuser to execute the commands.

Something like

myuser at myhost ~/ $

In tutorials thats often abbreviated to just the last characer:

>

or

$

or

#

To run pip you can invoke it directly from the OS  command
prompt

> pip ....

However current thinking favours rinning pip from inside Python
so you would type:

> python -m pip ...

So that means at the OS prompt type python -m pip

followed by whatever pip options you need.

Finally, individual programs can have a command line, or prompt,
inside them too. Python is one such.

When you run python with no extra arguments you get the Python
interpreter which usually has a >>> prompt. There you can enter
Python commands and see the result immediately. This is a very
useful tool for exploring how Python commands work.

$ python
<some blurbb here...>
>>> print("Hello")
Hello
>>> help(print)
<explanation of print command here....>

When following tutorials make sure you are clear which command
line is being used - the OS or Python. Check the prompt symbol.

Hopefully that's enough to get you started. If you are still
having issues get back to us but tell us which OS you are using
and exactly how far you got.

Cut 'n paste any commands and error messages into the mail,
do NOT include screenshots as the server will throw them away.

Finally, check out the "Getting Started" topic in my
tutorial(see below) for more info on getting started
with the command line.

-- 
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  Thu Dec 24 12:41:51 2020
From: mats at wichmann.us (Mats Wichmann)
Date: Thu, 24 Dec 2020 10:41:51 -0700
Subject: [Tutor] Command Lines
In-Reply-To: <CAGBm6oF2USoOHrXE4fPGcTtQ-FwGy_Cs2rYcVaeBi8cHxD25Ew@mail.gmail.com>
References: <CAGBm6oF2USoOHrXE4fPGcTtQ-FwGy_Cs2rYcVaeBi8cHxD25Ew@mail.gmail.com>
Message-ID: <36fc3b8c-e934-256f-48e3-5688f5b21362@wichmann.us>

On 12/23/20 10:48 PM, GardeGlory wrote:
> Hey y'all! I hope you and your teams are doing well this Christmas season.I
> know that this is by far not the preferred method of communication or help
> for this type of problem, but I am mentally exhausted from countless hours
> of forum searching and youtube videos... The reason I am reaching out is
> that I am new to the Python scene and am trying to set up a basic web
> scraping script, however, I ran into a "pip install" problem, so, after
> hours of scrounging around trying to figure out what a "command line" is,
> can you guys give me a step-by-step to try and dumb it down for me? What is
> a command line? And how do I go from it to doing something like "pip
> install requests"? Any help would be great, thank you so much, GardeGlory.

Alan Gault has given you what you to know, just wanted to put it very 
simply:

pip is a separate command on the same level as python, not something you 
type to a Python prompt, so you start it just like you start python. 
Except on Windows, you often expect to start Python by clicking on 
something (which will never be the case for pip), so it takes a little 
extra knowledge.  You can also, and this is preferred, run pip by giving 
command-line arguments to Python.

It shouldn't be that hard to find information on a command shell, 
certainly not hours of research.  Here's a Microsoft basic page, 
although it's not actually very descriptive, so this link is just to 
show this is a very basic thing:

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

(I cut this replay down to just the tutor mailing list).


From wilbur6453 at gmail.com  Fri Dec 25 10:36:10 2020
From: wilbur6453 at gmail.com (Mike Wilbur)
Date: Fri, 25 Dec 2020 10:36:10 -0500
Subject: [Tutor] Python Regex re.search() to parse system logs
In-Reply-To: <20201222060606.GA23693@cskk.homeip.net>
References: <CAF41aGH5iNjh-m8mPGmDJ4pzQOOU-irGigYu2CxNaaZRiDkn6w@mail.gmail.com>
 <20201222060606.GA23693@cskk.homeip.net>
Message-ID: <CAF41aGGvm3D91CbkuNKck6MmLWt9nvmBOT4uoBYPS_7X===oag@mail.gmail.com>

Cameron,
Thank you for the help.  I've read through it and I'm understanding the
logic!  I can't believe I wasn't using "r" for raw strings.  I'll let you
know how it all goes but I'm confident.
Again, thanks
Mike

On Tue, Dec 22, 2020 at 1:06 AM Cameron Simpson <cs at cskk.id.au> wrote:

> Comments below...
>
> On 21Dec2020 17:48, Mike Wilbur <wilbur6453 at gmail.com> wrote:
> >print(show_time_of_pid("Jul 6 14:01:23 computer.name CRON[29440]: USER
> >(good_user)")) # call to run function with parameter
> ># Desired output per below:
> ># Jul 6 14:01:23 pid:29440
> >
> >My code so far keeps pulling in the string "computer.name CRON[".  I can
> >get the date & time OR the pid #.  But not by themselves.  I have not
> >looked at adding the "pid:" to the output yet.
> >
> >*My code:*
> >print(re.search("(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})", "Jul 6 14:01:23
> >computer.name CRON[29440]: USER (good_user)"))
>
> A recommendation: use "raw strings" when writing regexps:
>
>    r"(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})"
>
> or:
>
>    r'(^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})'
>
> That leading "r" marks this as a "raw string", which means in particular
> that backslahses are not special to Python. Since regexps use
> backslashes to represent character classes and other things, using a raw
> string prevents Python's own backslash stuff from getting in the way.
> You will have fewer accidents this way.
>
> ><re.Match object; span=(0, 39), match='Jul 6 14:01:23 computer.name
> >CRON[29440'>
> >
> >Produced code using group names that isolates desired output.  But this
> >will not work with re.search() I believe.
>
> It works just find with re.search. re.match and re.search both return
> "Match" objects, they just differ in where they start in the text.
>
> >I think I'd need to use re.sub() instead.
>
> No need.
>
> Let's look at your regexp (ignoring the quotes - they're just for
> Python):
>
>    (^[\w \:]{15}.*[^a-z\.CRON][0-9]{5})
>
> Brackets () in a regexp group a section as a single unit. You don't need
> brackets around the whole thing.
>
>    ^[\w \:]{15}.*[^a-z\.CRON][0-9]{5}
>
> Let's look at each part:
>
> ^           Start of string.
>
> [\w \:]     A single character which is a "word" character or a space or
>             a colon.
>
> {15}        Exactly 15 such characters.
>
> .*          Any number of characters (zero or more of '.', which is any
>             single character).
>
> [^a-z\.CRON] A single character which is not one of a-z, ., C, R, O, N.
>
> [0-9]       A digit. Which can also be written \d
> {5}         Exactly 5 such characters, so exactly 5 digits.
>
> I think your "CRON" above should be _outside_ the [] character range.
>
> I recommend starting with a sample input line and deciding how to match
> each piece alone. You often have a choice here - take the simplest
> choice available.
>
> So:
>
>     Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)
>
> Your "[\w :]{15}" looks good. Dates in these logs are a fixed length and
> this will be reliable.
>
> After that I tend to be less believing. So I'd match the spaces with
> \s+, meaning "1 or more space characters".
>
> A computer name may have several characters, but won't have whitespace.
> You know where it will be, so just match \S+, meaning "1 or more
> nonspace characters".
>
> "CRON" seems critical to you. You can match it literally just by writine
> CRON.
>
> Alternatively, you might want any service, not just cron, so you could
> match a word ending in digits in brackets. Eg \S+\[\d+\] meaning "one or
> more nonspace characters followed by a left square bracket followed by 1
> or more digits followed by a right square bracket".
>
> And so on.
>
> You do not need to match the entire line. Just stop!
>
> This lets you build up your regular expression progressively. Match the
> first thing. When that's good, add some more pattern and test again.
> Continue until you have matched everything that you need.
>
> Your plan to use named section is good: surround the important pieces in
>
>     (?<name>
>
> and
>
>     )
>
> Then the match object will have these names pieces for use by name
> later. See the Match.groupdict method. Example:
>
>     ptn = re,compile(r'your regexp in here')
>     m = ptn.match(your_input_line_here)
>     if not m:
>         print("NO MATCH")
>     else:
>         matches = m.groupdict()
>         # print the timestamp part of your match
>         print(matches['timestamp'])
>
> So start slowly: write a regexp, with named parts, that just matches the
> first thing. And print it by name as above. Then extend the expression
> one part at a time until everything matches.
>
> That way you only need to consider problems with the small thing you
> have added.
>
> Finally, note that most regexp patterns are "greedy". So .* will match
> zero or more. But as many as possible.
>
> You might be concerned that that would match the entire line of text.
> Well it would, _except_ that it will only match stuff as long as the
> rest of the pattern _also_ matches. So if using the whole line prevents
> the rest of the pattern matching, it backs off a character and tries
> again, making it shorter and shorter until the rest of the pattern does
> match.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From cs at cskk.id.au  Fri Dec 25 17:29:44 2020
From: cs at cskk.id.au (Cameron Simpson)
Date: Sat, 26 Dec 2020 09:29:44 +1100
Subject: [Tutor] Python Regex re.search() to parse system logs
In-Reply-To: <CAF41aGGvm3D91CbkuNKck6MmLWt9nvmBOT4uoBYPS_7X===oag@mail.gmail.com>
References: <CAF41aGGvm3D91CbkuNKck6MmLWt9nvmBOT4uoBYPS_7X===oag@mail.gmail.com>
Message-ID: <20201225222944.GA97589@cskk.homeip.net>

On 25Dec2020 10:36, Mike Wilbur <wilbur6453 at gmail.com> wrote:
>Thank you for the help.  I've read through it and I'm understanding the
>logic!  I can't believe I wasn't using "r" for raw strings.  I'll let you
>know how it all goes but I'm confident.
>Again, thanks
>Mike

Thanks for the feedback! (Often one wonders if one's post has even been 
seen.)

If you have followup questions, add those questions to this thread - it 
keeps it all together.

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

From alexkleider at protonmail.com  Fri Dec 25 19:27:57 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Sat, 26 Dec 2020 00:27:57 +0000
Subject: [Tutor] Python Regex re.search() to parse system logs
In-Reply-To: <20201225222944.GA97589@cskk.homeip.net>
References: <CAF41aGGvm3D91CbkuNKck6MmLWt9nvmBOT4uoBYPS_7X===oag@mail.gmail.com>
 <20201225222944.GA97589@cskk.homeip.net>
Message-ID: <p-wiXyNMpFDy2BYx5xB9yHwt_WBIPi2l7_FALu9Kc6wXvx9bfktGkWq-XfXqFeHQDON3Dki2_Mdf6ijV3XJrcGfk4XataUKLWKsp-9IvnE4=@protonmail.com>

??????? Original Message ???????
On Friday, December 25, 2020 2:29 PM, Cameron Simpson <cs at cskk.id.au> wrote:

> On 25Dec2020 10:36, Mike Wilbur wilbur6453 at gmail.com wrote:
>
> > Thank you for the help. I've read through it and I'm understanding the
> > logic! I can't believe I wasn't using "r" for raw strings. I'll let you
> > know how it all goes but I'm confident.
> > Again, thanks
> > Mike
>
> Thanks for the feedback! (Often one wonders if one's post has even been
> seen.)
>
Cameron,
You can be certain your posts are seen!
I mostly lurk but am constantly grateful for the advice provided by you and the other tutors.
Your contribution to this particular thread was especially elucidating (and I've saved a copy among my 'regex' notes.)
Wishing you and yours the best this holiday season.
Best wishes to all!
Alex Kleider

From robertvstepp at gmail.com  Fri Dec 25 19:36:04 2020
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 25 Dec 2020 18:36:04 -0600
Subject: [Tutor] Python Regex re.search() to parse system logs
In-Reply-To: <p-wiXyNMpFDy2BYx5xB9yHwt_WBIPi2l7_FALu9Kc6wXvx9bfktGkWq-XfXqFeHQDON3Dki2_Mdf6ijV3XJrcGfk4XataUKLWKsp-9IvnE4=@protonmail.com>
References: <CAF41aGGvm3D91CbkuNKck6MmLWt9nvmBOT4uoBYPS_7X===oag@mail.gmail.com>
 <20201225222944.GA97589@cskk.homeip.net>
 <p-wiXyNMpFDy2BYx5xB9yHwt_WBIPi2l7_FALu9Kc6wXvx9bfktGkWq-XfXqFeHQDON3Dki2_Mdf6ijV3XJrcGfk4XataUKLWKsp-9IvnE4=@protonmail.com>
Message-ID: <CANDiX9JmYhP0LpMKahPnsDWJ_0qsDwBnUoFFX+deE8yHpKXH3Q@mail.gmail.com>

On Fri, Dec 25, 2020 at 6:28 PM alexkleider via Tutor <tutor at python.org> wrote:
>
> ??????? Original Message ???????
> On Friday, December 25, 2020 2:29 PM, Cameron Simpson <cs at cskk.id.au> wrote:

> > Thanks for the feedback! (Often one wonders if one's post has even been
> > seen.)
> >
> Cameron,
> You can be certain your posts are seen!
> I mostly lurk but am constantly grateful for the advice provided by you and the other tutors.
> Your contribution to this particular thread was especially elucidating (and I've saved a copy among my 'regex' notes.)
> Wishing you and yours the best this holiday season.
> Best wishes to all!
> Alex Kleider

I'll add a hearty "Amen!" to all Alex says!!

Hope all on the Tutor list has a blessed holiday season!

boB

From alexkleider at protonmail.com  Sun Dec 27 21:50:47 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Mon, 28 Dec 2020 02:50:47 +0000
Subject: [Tutor] problem with pytest
Message-ID: <oScT1_791qLwcOh68vhvbSwDZLvuBUtmflKOicrut2dIlyOX9Ag32vLFXW6un-Fb6NQyyyfyveJm5ar_qXNCb2cNGLLoUJTGaguohaX7JUU=@protonmail.com>

I appreciate that pytest is not part of the standard library but since it appears to be so widely used...
was hoping for some help anyway.

Here's my directory structure:
main project directory: proj
under it are __init__.py
helpers.py
Tests/
helpers_test.py
__init__.py
Using Debian/GNU/Linux, python3.7 with PYTHONPATH set to my project directory.
Content of helpers.py:
#!/usr/bin/env python3
# File: helpers.py
import datetime
date_template = "%b %d, %Y"
def get_datestamp(date=None):
"""
Returns a string (for postal letters,) in the format 'Jul 03, 1945'.
If <date> is provided it must be type datetime.datetime or
datetime.date. If not provided, today's date is used.
"""
if date:
if (isinstance(date,datetime.date)
or isinstance(date, datetime.datetime)):
d = date
else:
print("helpers.get_datestamp got a bad argument")
sys.exit()
else:
d = datetime.date.today()
return d.strftime(date_template)

if __name__ == '__main__':
assert (get_datestamp() ==
datetime.date.today().strftime(date_template)
)
assert (get_datestamp(datetime.date(1945, 7, 3)) ==
"Jul 03, 1945")
print("Assertions passed.")

Content of Tests/helpers_test.py:
#!/usr/bin/env python3
# File: Tests/helpers_test.py
import pytest
import helpers
import datetime
@pytest.mark.parametrize("date_obj, expected", [
(datetime.date(1945, 7, 3), 'Jul 03, 1945'),
(datetime.date(1943, 7, 15), 'Jul 15, 1943'),
])
def test_get_datestamp_w_valid_datetime_params():
assert helpers.get_datestamp(date_obj) == expected

$ ./helpers.py # behaves as I'd expect
$ pytest # complains that ...
"In test_get_datestamp_w_valid_datetime_params: function uses no argument 'date_obj' "

Above is the bare minimum to illustrate the problem.
In my code I have other instances of the @pytest.mark.parametrize() decorator that work just fine.
There must be something simple here that I'm just not seeing.
Thanks in advance.
Cheers,
Alex Kleider

From alexkleider at protonmail.com  Mon Dec 28 20:34:27 2020
From: alexkleider at protonmail.com (alexkleider)
Date: Tue, 29 Dec 2020 01:34:27 +0000
Subject: [Tutor] problem with pytest
In-Reply-To: <nmjkufpmfc1q1e4akd25ta47ahkunops9u@4ax.com>
References: <oScT1_791qLwcOh68vhvbSwDZLvuBUtmflKOicrut2dIlyOX9Ag32vLFXW6un-Fb6NQyyyfyveJm5ar_qXNCb2cNGLLoUJTGaguohaX7JUU=@protonmail.com>
 <nmjkufpmfc1q1e4akd25ta47ahkunops9u@4ax.com>
Message-ID: <EP7AdYrnsHHCTDGhmMlrAUJo3bmS7nDSHzYrMFtg0ZxiR6Y4ExScDYqhjwS3DX-r0Uor42UWbcv4-xYkV671j7lEuTlsSOwvypl-XQvVtbo=@protonmail.com>

??????? Original Message ???????
On Monday, December 28, 2020 1:43 PM, Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote:

> Please find a different means to post -- Python is highly dependent
> upon indentation and your posting method has stripped out all leading
> indentation.

My apologies, to be sure.  I've recently switched to a different mail provider, and although all the indentation looks fine when I send, it appears not to be so upon arrival.  Will have to switch back.

> def test_get_datestamp_w_valid_datetime_params():
>
> has NO input arguments, so I would assume the decorator is unable to
> formulate invocations of the function.
>
> Perhaps
>
> def test_get_datestamp_w_valid_datetime_params(date_obj, expected):
>
> would resolve the problem?
>

It does indeed!  I looked at that for you wouldn't believe how long without seeing the problem which now that you've pointed it out is so obvious.
Thank you ever so much.

Alex
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>     Wulfraed                 Dennis Lee Bieber         AF6VN
>     wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
>
>
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



From shariesk at sundaelectronics.com  Mon Dec 28 22:01:12 2020
From: shariesk at sundaelectronics.com (Shari Eskenas)
Date: Mon, 28 Dec 2020 19:01:12 -0800
Subject: [Tutor] A picture book that teaches Python basics
Message-ID: <CACdgv5yvSk2jecFbXZPdN0qVh7Ra6ZdbQVyqZLVkzU_VZZwhxg@mail.gmail.com>

Hi everyone!

I'm writing a unique Python book for beginners called *A Day in Code:
Python. * It's a picture book that tells a story with Python programs that
represent real-life situations. It teaches Python basics with the code
examples that compose the story. It's currently on Kickstarter (ends Jan.
15th):

https://www.kickstarter.com/projects/914595512/a-day-in-code-python

I hope this book will be a fun and helpful resource for beginners learning
Python. :)

Best,
Shari Eskenas

From alan.gauld at yahoo.co.uk  Tue Dec 29 05:42:49 2020
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 29 Dec 2020 10:42:49 +0000
Subject: [Tutor] A picture book that teaches Python basics
In-Reply-To: <CACdgv5yvSk2jecFbXZPdN0qVh7Ra6ZdbQVyqZLVkzU_VZZwhxg@mail.gmail.com>
References: <CACdgv5yvSk2jecFbXZPdN0qVh7Ra6ZdbQVyqZLVkzU_VZZwhxg@mail.gmail.com>
Message-ID: <rsf179$k5s$1@ciao.gmane.io>

On 29/12/2020 03:01, Shari Eskenas wrote:

> I'm writing a unique Python book for beginners called *A Day in Code:
> Python. * It's a picture book that tells a story with Python programs that
> represent real-life situations. It teaches Python basics with the code
> examples that compose the story. It's currently on Kickstarter (ends Jan.
> 15th):
> 
> https://www.kickstarter.com/projects/914595512/a-day-in-code-python
> 
> I hope this book will be a fun and helpful resource for beginners learning
> Python. :)

>From one author to another I wish you well.

That is a very challenging format, I've seen at least 2 other attempts
to teach programming using pictures, neither was very successful.
The fundamental problem being that programming (Scratch and
Turbovision aside) is a fundamentally textual process. How to
convey that in a pictorial style is hard to imagine, but you
obviously have some ideas. I look forward to seeing what you
produce.

-- 
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 adameyring at gmail.com  Tue Dec 29 11:16:50 2020
From: adameyring at gmail.com (Adam Eyring)
Date: Tue, 29 Dec 2020 11:16:50 -0500
Subject: [Tutor] A picture book that teaches Python basics
In-Reply-To: <CACdgv5yvSk2jecFbXZPdN0qVh7Ra6ZdbQVyqZLVkzU_VZZwhxg@mail.gmail.com>
References: <CACdgv5yvSk2jecFbXZPdN0qVh7Ra6ZdbQVyqZLVkzU_VZZwhxg@mail.gmail.com>
Message-ID: <CAPStRW_U-HipZkM8LgAR2o1tDJKcxz1sR-Z+f_cGMONuM8U9oA@mail.gmail.com>

On Tue, Dec 29, 2020 at 4:44 AM Shari Eskenas <shariesk at sundaelectronics.com>
wrote:

> Hi everyone!
>
> I'm writing a unique Python book for beginners called *A Day in Code:
> Python. * It's a picture book that tells a story with Python programs that
> represent real-life situations. It teaches Python basics with the code
> examples that compose the story. It's currently on Kickstarter (ends Jan.
> 15th):
>
> https://www.kickstarter.com/projects/914595512/a-day-in-code-python
>
> I hope this book will be a fun and helpful resource for beginners learning
> Python. :)
>
> Best,
> Shari Eskenas
>

Shari,
Looks great. I learned some Python basics from books by Raspberry Pi press
and they were written in a way that a middle-aged person like me wouldn't
be overwhelmed. It gave me the confidence to use
other more complex resources so I can use Python for data science. Your
book looks very promising and I highly recommend you teach something like
an after-school club (with access to computers) how to do Python using your
book.

AME




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