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: References: <6jfasfh0pldror3e7cehf8h9t7297jq0dn@4ax.com> Message-ID: 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 | blog github 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: 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: References: Message-ID: 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: References: Message-ID: 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 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: References: Message-ID: <20201202043559.GA77918@cskk.homeip.net> On 02Dec2020 08:03, Manprit Singh 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 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: 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: References: Message-ID: 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, 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: 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: References: 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: References: <23586c1a-11de-ab45-a2e0-984f7e7547c9@gmail.com> Message-ID: 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: 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: References: <5FCCDE8E.1090205.ref@sbcglobal.net> <5FCCDE8E.1090205@sbcglobal.net> <2ef3f244-b65b-3dce-c68e-350314adc41d@wichmann.us> <5FCD1556.4030107@sbcglobal.net> 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 > 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: > 123456 > 123456 > 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> <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 >> 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: >> ??????????????? 123456 >> ??????????????? 123456 >> ??????????????? 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> <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 >>> 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: 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: References: 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: References: Message-ID: 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 .tar.gz archive and file it in the . The archive is to contain all files &/or directories listed in (a list.) Fails if a directory 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 and 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: 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 .tar.gz archive and > file it in the . > The archive is to contain all files &/or directories > listed in (a list.) > Fails if a directory 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 and 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: References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com> Message-ID: ??????? Original Message ??????? On Thursday, December 10, 2020 2:10 AM, Alan Gauld via Tutor 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 and 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 .tar.gz archive and file it in the . The archive is to contain all files &/or directories listed in all under a directory called . Fails if a directory 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: References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com> Message-ID: 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: References: <7Z2IkLi-bwL2-U0j5nyifejRLL09kvYAbJaPn98EO_xggiGwBojlautIB_Poo4SiG6EXtsQLeiUzzEJPdgw3Xh0BeCzx9B_8e5KwAW0Fc7M=@protonmail.com> Message-ID: ??????? Original Message ??????? On Friday, December 11, 2020 1:36 AM, Alan Gauld via Tutor 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: 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: References: Message-ID: 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: References: Message-ID: <20201215215917.GA89219@cskk.homeip.net> On 15Dec2020 19:11, nathan tech 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 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: References: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: 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: 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: References: Message-ID: 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: 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)")) 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[\w \:]{15}).*[^a-zCRON].*\[(?P[\d]{5})\]", "Jul 6 14:01:23 computer.name CRON[29440]: USER (good_user)"))* [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: References: Message-ID: <20201222060606.GA23693@cskk.homeip.net> Comments below... On 21Dec2020 17:48, Mike Wilbur 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. > > >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 (? 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 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: 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 "", line 1, in 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: 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: References: Message-ID: 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 >>> print("Hello") Hello >>> help(print) 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: References: 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: <20201222060606.GA23693@cskk.homeip.net> Message-ID: 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 wrote: > Comments below... > > On 21Dec2020 17:48, Mike Wilbur 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. > > > > > > >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 > > (? > > 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 > _______________________________________________ > 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: References: Message-ID: <20201225222944.GA97589@cskk.homeip.net> On 25Dec2020 10:36, Mike Wilbur 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 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: <20201225222944.GA97589@cskk.homeip.net> Message-ID: ??????? Original Message ??????? On Friday, December 25, 2020 2:29 PM, Cameron Simpson 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: References: <20201225222944.GA97589@cskk.homeip.net> Message-ID: On Fri, Dec 25, 2020 at 6:28 PM alexkleider via Tutor wrote: > > ??????? Original Message ??????? > On Friday, December 25, 2020 2:29 PM, Cameron Simpson 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: 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 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: References: Message-ID: ??????? Original Message ??????? On Monday, December 28, 2020 1:43 PM, Dennis Lee Bieber 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: 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: References: Message-ID: 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: References: Message-ID: On Tue, Dec 29, 2020 at 4:44 AM Shari Eskenas 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 >