Re: [Tutor] Pythonic way
On 20/11/2018 22:35, Steven D'Aprano wrote: > On Tue, Nov 20, 2018 at 08:22:01PM +, Alan Gauld via Tutor wrote: > >> I think that's a very deliberate feature of Python going back >> to its original purpose of being a teaching language that >> can be used beyond the classroom. > > I don't think that is correct -- everything I've read is that Guido > designed Python as a scripting language for use in the "Amoeba" > operating system. I think both are true. Guido was working on Amoeba at the time he built Python so it was an obvious choice of platform, although he first built it on a Mac. But he didn't set out specifically to build a scripting language for Amoeba but rather to build "a descendant of ABC" which was also usable in the real world, specifically The C/Unix world. To do that he believed it had to address the major barriers to ABC which were 1)being capable of being extended and 2) improved I/O. My source for that conclusion is Guido's forward to "Programming Python" 1st edition. https://www.python.org/doc/essays/foreword/ Also his comments when he set up the "Computer Programming for Everybody" initiative, which he led for several years. (Which I can't locate...) So I believe that ease of teaching was definitely part of the original game plan and was definitely a factor in some of the later developments around v2.0 or so. -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way
On Tue, Nov 20, 2018 at 08:22:01PM +, Alan Gauld via Tutor wrote: > I think that's a very deliberate feature of Python going back > to its original purpose of being a teaching language that > can be used beyond the classroom. I don't think that is correct -- everything I've read is that Guido designed Python as a scripting language for use in the "Amoeba" operating system. You might be thinking of Python's major influence, ABC, which was designed as a teaching language -- but not by Guido himself. Guido was heavily influenced by ABC, both in what to do, and what not to do. https://www.artima.com/intv/pythonP.html http://python-history.blogspot.com/2009/02/early-language-design-and-development.html -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way
On 20/11/2018 18:08, Avi Gross wrote: We have two completely separate ways to format strings that end up with fairly similar functionality. Actually, there is an implicit third way You could argue five ways :-) 1. C printf style formatting https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting 2. New style string formatting https://docs.python.org/3/library/string.html#string-formatting 3. f-strings https://docs.python.org/3/reference/lexical_analysis.html#f-strings 4. String templates https://docs.python.org/3/library/string.html#template-strings 5. String methods https://docs.python.org/3/library/stdtypes.html#string-methods Any advance on five anybody? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way
On 20/11/2018 18:08, Avi Gross wrote: > ... So there isn’t really ONE pythonic way for many things. That's true and, I think, inevitable for anything developed in the open source world. If you compare it to a language entirely controlled by a single mind - like Oberon or Eiffel say - then there is much less consistency. But how many people actually use Oberon or Eiffel in the real world these days? > We have two completely separate ways to format strings And many options for concurrency and for running external programs. Much of it is history and the need for backward compatibility. And let's not even think about web and GUI frameworks! > ..you can do much without creating objects or using functional programming > ...If you come from an OO background, you can have fun making endless classes >...If you lie functional programming with factories that churn out functions > ...There are other such paradigms supported including lots of miniature > sub-languages > ...effectively means being open to multiple ways I think that's a very deliberate feature of Python going back to its original purpose of being a teaching language that can be used beyond the classroom. It was always intended to support multi paradigms. After all, every programmer should be aware of multiple paradigms and when to best use each. BUt, Python is currently suffering the same fate as C++ in that, as it becomes more mainstream in real-world industry, the feature demands upon it inevitably move it away from some of those original teaching based ideas. It is certainly a much harder language to learn today than it was when I started in 1998. From a pure academic CS view many changes are good (eg. iterators and meta programming) but from a non-academic beginner(or even high school student) they are just plain confusing. It's all part of being a success in the real world. The funding for development comes from the industrial user community not the high schools or colleges, so their needs come first. PS. Just back from vacation so still catching up on the last week's discussions! -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic way
This is not a question or reply. Nor is it short. If not interested, feel free to delete. It is an observation based on recent experiences. We have had quite a few messages that pointed out how some people approach solving a problem using subconscious paradigms inherited from their past. This includes people who never programmed and are thinking of how they might do it manually as well as people who are proficient in one or more other computer languages and their first attempt to visualize the solution may lead along paths that are possibly doable in Python but not optimal or even suggested. I recently had to throw together a routine that would extract info from multiple SAS data files and join them together on one key into a large DataFrame (or data.frame or other such names for a tabular object.). Then I needed to write them out to disk either as a CSV or XLSX file for future use. Since I have studied and used (not to mention abused) many programming languages, my first thought was to do this in R. It has lots of the tools needed to do such things including packages (sort of like modules you can import but not exactly) and I have done many data/graphics programs in it. I then redid it in Python after some thought. The pseudocode outline is: * Read in all the files into a set of data.frame objects. * Trim back the variables/columns of some of them as many are not needed. * Join them together on a common index using a full or outer join. * Save the result on disk as a Comma Separated Values file. * Save the result on disk as a named tab in a new style EXCEL file. I determined some of what I might us such as the needed built-in commands, packages and functions I could use for the early parts but ran into an annoyance as some of the files contained duplicate entries. Luckily, the R function reduce (not the same as map/reduce) is like many things in R and takes a list of items and makes it work. Also, by default, it renames duplicates so if you have ALPHA in multiple places, it names them ALPHA.x and ALPHA.x.x and other variations. df_joined <- reduce(df_list, full_join, by = "COMMON") Mind you, when I stripped away many of the columns not needed in some of the files, there were fewer duplicates and a much smaller output file. But I ran into a wall later. Saving into a CSV is trivial. There are multiple packages meant to be used for saving into a XLSX file but they all failed for me. One wanted something in JAVA and another may want PERL and some may want packages I do not have installed. So, rather than bash my head against the wall, Itwisted and used the best XSLX maker there is. I opened the CSV file in EXCEL manually and did a SAVE AS … Then I went to plan C (no, not the language C or its many extensions like C++) as I am still learning Python and have not used it much. As an exercise, I decided to learn how to do this in Python using tools/modules like numpy and pandas that I have not had much need for as well as additional tools for reading and writing files in other formats. My first attempts gradually worked, after lots of mistakes and looking at manual pages. It followed an eclectic set of paradigms but worked. Not immediately, as I ran into a problem in that the pandas version of a join did not tolerate duplicate column names when used on a list. I could get it to rename the left or right list (adding a suffix a suffix) when used on exactly two DataFrames. So, I needed to take the first df and do a df.join(second, …) then take that and join the third and so on. I also needed to keep telling it to set the index to the common value for each and every df including the newly joined series. And, due to size, I chose to keep deleting df no longer in use but that would not be garbage collected. I then looked again at how to tighten it up in a more pythonic way. In English (my sixth language since we are talking about languages ) I did some things linearly then shifted it to a list method. I used lists of file names and lists of the df made from each file after removing unwanted columns. (NOTE: I use “column” but depending on language and context I mean variable or field or axis or many other ways to say a group of related information in a tabular structure that crosses rows or instances.) So I was able to do my multi-step join more like this: join_with_list = dflist[1:] current = df1 suffix = 1 for df in join_with_list: current = current.join(df, how='outer', rsuffix='_'+str(suffix)) suffix += 1 current.set_index('ID') In this formulation, the intermediate DataFrame objects held in current will silently be garbage collected as nothing points to them, for example. Did I mention these were huge files? The old code was much longer and error prone as I had a df1, df2, … df8 as well as other intermediates and was easy to copy and paste then
Re: [Tutor] pythonic
Op 2 apr. 2018 15:31 schreef Steven D'Aprano: > > On Mon, Apr 02, 2018 at 06:49:52AM -0600, Mats Wichmann wrote: > > On 04/02/2018 02:56 AM, Alan Gauld via Tutor wrote: > > > On 02/04/18 04:19, Steven D'Aprano wrote: > > >> On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote: > > >>> On01/04/18 20:20, Albert-Jan Roskam wrote: > > fmt="%Y-%m-%d %H:%M\n" > > f.write(now.strftime(fmt)) > > Lately I've been using format(), which uses __format__, because I find > > it slightly more readable: > > format(datetime.now(), "%Y-%m-%d %H:%M") > > >>> Interesting, > > >>> I didn't know that format() recognised the datetime format codes. > > >> It doesn't. It is the datetime object that recognises them. format() > > >> merely passes the format string to the datetime.__format__ method, which > > >> is what recognises the codes. It doesn't care what it is. > > > Aha! That makes sense. I've never really used format() so have never > > > bothered to find out how it works. To the point that until this thread I > > > hadn't realized we even had a __format__() operator. > > > > > > As I said, I need to do some reading. Obviously a gap in my python > > > education. > > > > > > > so since we're all learning things here, how would this play out with > > the new f-strings? > > I don't think f-strings are even a bit Pythonic. "There should be one-- and preferably only one --obvious way to do it.": 1-str.format 2-% interpolation 3-string.Template 4-f strings -... I think that at least a few of these methods should become deprecated. Maybe 2 and 3? (though I use 2 all the time!). Not sure about 4. A proper templating language like Jinja might be more desirable to have in the standard library, addition to a simple string substitution mechanism ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On Mon, Apr 02, 2018 at 04:28:10PM +0200, Peter Otten wrote: > > They look like string constants, but they're actually a hidden call to > > eval(). > > But because you cannot f-ify a string variable (without an additional eval() > call) you aren't tempted to feed them user-provided data. If only that were the case... https://mail.python.org/pipermail/python-list/2018-March/731967.html He reads f-strings from user-supplied data, then evals them. But its okay, he's only doing it within his own organisation, and we all know that "insiders" are always 100% trusted. "Insider attack" is just a pair of words. Right? > As I'm getting tired of writing > > "...{foo}...{bar}...".format(foo=foo, bar=bar, ...) You can write: template.format(**(locals())) or possibly nicer still: template.format_map(locals()) -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On 04/02/2018 08:28 AM, Peter Otten wrote: > Steven D'Aprano wrote: > >> On Mon, Apr 02, 2018 at 06:49:52AM -0600, Mats Wichmann wrote: > >>> so since we're all learning things here, how would this play out with >>> the new f-strings? >> >> I don't think f-strings are even a bit Pythonic. >> >> They look like string constants, but they're actually a hidden call to >> eval(). > > But because you cannot f-ify a string variable (without an additional eval() > call) you aren't tempted to feed them user-provided data. > >> They can only be used once, and are not re-usable (unlike proper >> templates): > > You can't eat your cake an have it. As "proper templates" they would indeed > be as dangerous as eval(). > >> By my count, they violate at least three of the Zen of Python: >> >> Explicit is better than implicit. >> Simple is better than complex. >> Special cases aren't special enough to break the rules. > > As I'm getting tired of writing > > "...{foo}...{bar}...".format(foo=foo, bar=bar, ...) > > lately I'd say they win big in the "practicality beats you-name-it" area. so swooping back to the origial code, it seems there are several options for expressing the output. Picking one of the lines (and replacing the writes to a file with prints for simplicity): print("Date: {}-{}-{} {}:{}\n".format(now.year, now.month, now.day, now.hour, now.minute)) print("Date:", format(now, "%Y-%m-%d %H:%M")) print(f"Date: {now:%Y-%m-%d %H:%M}") those aren't exactly identical, since the using %m-%d form causes zero-padding: Date: 2018-4-2 10:23 Date: 2018-04-02 10:23 Date: 2018-04-02 10:23 For me, I don't know if the f-string version is the most Pythonic, but it has an appealing conciseness in this particular context :) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
Steven D'Aprano wrote: > On Mon, Apr 02, 2018 at 06:49:52AM -0600, Mats Wichmann wrote: >> so since we're all learning things here, how would this play out with >> the new f-strings? > > I don't think f-strings are even a bit Pythonic. > > They look like string constants, but they're actually a hidden call to > eval(). But because you cannot f-ify a string variable (without an additional eval() call) you aren't tempted to feed them user-provided data. > They can only be used once, and are not re-usable (unlike proper > templates): You can't eat your cake an have it. As "proper templates" they would indeed be as dangerous as eval(). > By my count, they violate at least three of the Zen of Python: > > Explicit is better than implicit. > Simple is better than complex. > Special cases aren't special enough to break the rules. As I'm getting tired of writing "...{foo}...{bar}...".format(foo=foo, bar=bar, ...) lately I'd say they win big in the "practicality beats you-name-it" area. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On Mon, Apr 02, 2018 at 06:49:52AM -0600, Mats Wichmann wrote: > On 04/02/2018 02:56 AM, Alan Gauld via Tutor wrote: > > On 02/04/18 04:19, Steven D'Aprano wrote: > >> On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote: > >>> On01/04/18 20:20, Albert-Jan Roskam wrote: > fmt="%Y-%m-%d %H:%M\n" > f.write(now.strftime(fmt)) > Lately I've been using format(), which uses __format__, because I find > it slightly more readable: > format(datetime.now(), "%Y-%m-%d %H:%M") > >>> Interesting, > >>> I didn't know that format() recognised the datetime format codes. > >> It doesn't. It is the datetime object that recognises them. format() > >> merely passes the format string to the datetime.__format__ method, which > >> is what recognises the codes. It doesn't care what it is. > > Aha! That makes sense. I've never really used format() so have never > > bothered to find out how it works. To the point that until this thread I > > hadn't realized we even had a __format__() operator. > > > > As I said, I need to do some reading. Obviously a gap in my python > > education. > > > > so since we're all learning things here, how would this play out with > the new f-strings? I don't think f-strings are even a bit Pythonic. They look like string constants, but they're actually a hidden call to eval(). py> x = 2 py> f'hello {3*x}' 'hello 6' So they can execute arbitrary code that has arbitrary side-effects: py> L = [] py> f'hello {L.append(1) or 99}' 'hello 99' py> L [1] By my count, they violate at least three of the Zen of Python: Explicit is better than implicit. Simple is better than complex. Special cases aren't special enough to break the rules. They can only be used once, and are not re-usable (unlike proper templates): py> x = 2 py> template = f'x = {x}' # gets the value of x now py> print(template) x = 2 py> x = 99 py> print(template) # still has the old value of x x = 2 However, they do use the same mechanism as format(): py> from datetime import datetime py> t = datetime.now() py> format(t, '%H:%M') '23:22' py> f'{t:%H:%M}' '23:22' -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On Mon, Apr 2, 2018 at 9:01 AM, David Rockwrote: > It’s just as (if not more) pythonic to use the standard libraries. It’s very > common in a professional environment to not have access to outside (i.e., > internet) resources. I wouldn’t venture into Pypi unless there’s something > you can’t do well with what’s already provided by default. +1. Use standard libraries; most places I've worked didn't allow a lot of non-standard library code at all. If something is in the standard library you have some level of assurance that the maintenance is moderated and monitored. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
> On Mar 30, 2018, at 04:15, George Fischhofwrote: > > 2.) > argparse > > it is good, but you can write more Pythonic code using click > https://pypi.python.org/pypi/click/ > it is also Pythonic to use / know the Python ecosystem (the packages) It’s just as (if not more) pythonic to use the standard libraries. It’s very common in a professional environment to not have access to outside (i.e., internet) resources. I wouldn’t venture into Pypi unless there’s something you can’t do well with what’s already provided by default. — David Rock da...@graniteweb.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On 04/02/2018 02:56 AM, Alan Gauld via Tutor wrote: > On 02/04/18 04:19, Steven D'Aprano wrote: >> On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote: >>> On01/04/18 20:20, Albert-Jan Roskam wrote: fmt="%Y-%m-%d %H:%M\n" f.write(now.strftime(fmt)) Lately I've been using format(), which uses __format__, because I find it slightly more readable: format(datetime.now(), "%Y-%m-%d %H:%M") >>> Interesting, >>> I didn't know that format() recognised the datetime format codes. >> It doesn't. It is the datetime object that recognises them. format() >> merely passes the format string to the datetime.__format__ method, which >> is what recognises the codes. It doesn't care what it is. > Aha! That makes sense. I've never really used format() so have never > bothered to find out how it works. To the point that until this thread I > hadn't realized we even had a __format__() operator. > > As I said, I need to do some reading. Obviously a gap in my python > education. > so since we're all learning things here, how would this play out with the new f-strings? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On 02/04/18 04:19, Steven D'Aprano wrote: > On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote: >> On01/04/18 20:20, Albert-Jan Roskam wrote: >>> fmt="%Y-%m-%d %H:%M\n" >>> f.write(now.strftime(fmt)) >>> Lately I've been using format(), which uses __format__, because I find it >>> slightly more readable: >>> format(datetime.now(), "%Y-%m-%d %H:%M") >> Interesting, >> I didn't know that format() recognised the datetime format codes. > It doesn't. It is the datetime object that recognises them. format() > merely passes the format string to the datetime.__format__ method, which > is what recognises the codes. It doesn't care what it is. Aha! That makes sense. I've never really used format() so have never bothered to find out how it works. To the point that until this thread I hadn't realized we even had a __format__() operator. As I said, I need to do some reading. Obviously a gap in my python education. -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote: > On01/04/18 20:20, Albert-Jan Roskam wrote: > > fmt="%Y-%m-%d %H:%M\n" > > f.write(now.strftime(fmt)) > > Lately I've been using format(), which uses __format__, because I find it > > slightly more readable: > > format(datetime.now(), "%Y-%m-%d %H:%M") > Interesting, > I didn't know that format() recognised the datetime format codes. It doesn't. It is the datetime object that recognises them. format() merely passes the format string to the datetime.__format__ method, which is what recognises the codes. It doesn't care what it is. py> class Spam: ... def __format__(self, template): ... return template.replace("^DD^", " surprise ") ... py> format(Spam(), "some^DD^string") 'some surprise string' -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On01/04/18 20:20, Albert-Jan Roskam wrote: > fmt="%Y-%m-%d %H:%M\n" > f.write(now.strftime(fmt)) > Lately I've been using format(), which uses __format__, because I find it > slightly more readable: > format(datetime.now(), "%Y-%m-%d %H:%M") Interesting, I didn't know that format() recognised the datetime format codes. I assumed it would just use the printf codes. Time to do some more reading I see. -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On Mar 30, 2018 10:39, Alan Gauld via Tutorwrote: > > On 30/03/18 03:48, Pat Martin wrote: > > > the "right" way to do it in python? > > More or less, a couple of comments below... > > > def Main(): > > Python function names begin with a lowercase letter by convention. > > > """Run if run as a program.""" > > parser = argparse.ArgumentParser() > ... > > > > > now = datetime.datetime.now() > > slug = args.title.replace(" ", "-").lower() > > > > with open("{}.md".format(slug), 'w') as f: > > f.write("Title: {}\n".format(args.title)) > > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > > now.month, > > now.day, > > now.hour, > > now.minute)) > > Formatting of dates and times is usually done using > the time.strftime function which is specifically > designed for that. It might be worth taking a peek > at the docs on that one. You can call it directly > on a datetime object - 'now' in your case: > > fmt="%Y-%m-%d %H:%M\n" > f.write(now.strftime(fmt)) Lately I've been using format(), which uses __format__, because I find it slightly more readable: format(datetime.now(), "%Y-%m-%d %H:%M") ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
Thank you all for the ideas and comments, it is appreciated. I have some refactoring to do now. On Fri, Mar 30, 2018 at 2:22 AM, Peter Otten <__pete...@web.de> wrote: > Pat Martin wrote: > > > I have written the following program. It generates a template for Pelican > > web site static generator. It works just fine, it generates the template > > and then I put the info in it to customize. But I was wondering, is this > > the "right" way to do it in python? > > You may rewrite the code creating the output as a loop: > > now_str = now.replace(microsecond=0).isoformat(" ") > with open("{}.md".format(slug), 'w') as f: > for name, value in [ > ("Title", args.title), > ("Date", now_str), > ("Modified", now_str), > ("Category", args.category), > ("Slug", slug), > ("Authors", args.author), > ("Summary", ""), > ]: > print(name, value, sep=": ", file=f) > > > If you want to format more than one date the same way you should put the > code into a function, no matter whether you pick your, my, or Alan's much > more common way to implement it > > def format_time(dt): >return ... > > ... > ("Date", format_time(now)), > ("Modified", format_time(modified)), > ... > > The idea behind my suggestions is the DRY (don't repeat yourself) principle > which applies to code written in any language. > > > #!/usr/bin/env python3 > > """Generate a Pelican markdown base page.""" > > > > import argparse > > import datetime > > > > > > def Main(): > > """Run if run as a program.""" > > parser = argparse.ArgumentParser() > > parser.add_argument("-T", "--title", type=str, required=True, > > help='Title for site, also generates the slug', > > metavar="") > > parser.add_argument("-c", "--category", required=True, > > help='Category or categories of post', > metavar="") > > parser.add_argument("-t", "--tags", type=str, required=True, > > help="Tags for post", metavar="") > > parser.add_argument("-a", "--author", type=str, default="Pat Martin", > > help="Author of post", metavar="") > > args = parser.parse_args() > > > > now = datetime.datetime.now() > > slug = args.title.replace(" ", "-").lower() > > > > with open("{}.md".format(slug), 'w') as f: > > f.write("Title: {}\n".format(args.title)) > > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > > now.month, > > now.day, > > now.hour, > > now.minute)) > > f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, > > now.month, > > now.day, > > now.hour, > > now.minute)) > > f.write("Category: {}\n".format(args.category)) > > f.write("Slug: {}\n".format(slug)) > > f.write("Authors: {}\n".format(args.author)) > > f.write("Summary: \n") > > > > > > if __name__ == "__main__": > > Main() > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
2018-03-30 4:48 GMT+02:00 Pat Martin: > Hello all, > > I have written the following program. It generates a template for Pelican > web site static generator. It works just fine, it generates the template > and then I put the info in it to customize. But I was wondering, is this > the "right" way to do it in python? > > #!/usr/bin/env python3 > """Generate a Pelican markdown base page.""" > > import argparse > import datetime > > > def Main(): > """Run if run as a program.""" > parser = argparse.ArgumentParser() > parser.add_argument("-T", "--title", type=str, required=True, > help='Title for site, also generates the slug', > metavar="") > parser.add_argument("-c", "--category", required=True, > help='Category or categories of post', metavar="") > parser.add_argument("-t", "--tags", type=str, required=True, > help="Tags for post", metavar="") > parser.add_argument("-a", "--author", type=str, default="Pat Martin", > help="Author of post", metavar="") > args = parser.parse_args() > > now = datetime.datetime.now() > slug = args.title.replace(" ", "-").lower() > > with open("{}.md".format(slug), 'w') as f: > f.write("Title: {}\n".format(args.title)) > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > now.month, > now.day, > now.hour, > now.minute)) > f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, > now.month, > now.day, > now.hour, > now.minute)) > f.write("Category: {}\n".format(args.category)) > f.write("Slug: {}\n".format(slug)) > f.write("Authors: {}\n".format(args.author)) > f.write("Summary: \n") > > > if __name__ == "__main__": > Main() > > > > Thanks for any input. > > WP > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Hi Pat, my thoughts: 1.) def Main(): function names are written with small letter with underscore between the words check PEP-8 https://www.python.org/dev/peps/pep-0008/ http://docs.python-guide.org/en/latest/writing/style/ It is better to name the functions according to what they do, in this case for example: create_template() or something like that 2.) argparse it is good, but you can write more Pythonic code using click https://pypi.python.org/pypi/click/ it is also Pythonic to use / know the Python ecosystem (the packages) 3.) with open("{}.md".format(slug), 'w') as f: f.write("Date: {}-{}-{} {}:{}\n".format(now.year, now.month, Python is mainly about readability https://www.python.org/dev/peps/pep-0020/ you can use more meaningful variable names: template_file instead of f if you have Python 3.6, you can use the newest formatting method, which is more readable: template_file.write(f"Date: {now.moth}-{now.day}") etc https://www.python.org/dev/peps/pep-0498/ the more readable open: slug_file_name = f"{slug}.md" with open(slug_file_name, "w") as slug_file: and if you use Python 3, the open should contain encoding: with open(slug_file_name, "w", encoding="UTF-8") as slug_file: BR, George ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
Pat Martin wrote: > I have written the following program. It generates a template for Pelican > web site static generator. It works just fine, it generates the template > and then I put the info in it to customize. But I was wondering, is this > the "right" way to do it in python? You may rewrite the code creating the output as a loop: now_str = now.replace(microsecond=0).isoformat(" ") with open("{}.md".format(slug), 'w') as f: for name, value in [ ("Title", args.title), ("Date", now_str), ("Modified", now_str), ("Category", args.category), ("Slug", slug), ("Authors", args.author), ("Summary", ""), ]: print(name, value, sep=": ", file=f) If you want to format more than one date the same way you should put the code into a function, no matter whether you pick your, my, or Alan's much more common way to implement it def format_time(dt): return ... ... ("Date", format_time(now)), ("Modified", format_time(modified)), ... The idea behind my suggestions is the DRY (don't repeat yourself) principle which applies to code written in any language. > #!/usr/bin/env python3 > """Generate a Pelican markdown base page.""" > > import argparse > import datetime > > > def Main(): > """Run if run as a program.""" > parser = argparse.ArgumentParser() > parser.add_argument("-T", "--title", type=str, required=True, > help='Title for site, also generates the slug', > metavar="") > parser.add_argument("-c", "--category", required=True, > help='Category or categories of post', metavar="") > parser.add_argument("-t", "--tags", type=str, required=True, > help="Tags for post", metavar="") > parser.add_argument("-a", "--author", type=str, default="Pat Martin", > help="Author of post", metavar="") > args = parser.parse_args() > > now = datetime.datetime.now() > slug = args.title.replace(" ", "-").lower() > > with open("{}.md".format(slug), 'w') as f: > f.write("Title: {}\n".format(args.title)) > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > now.month, > now.day, > now.hour, > now.minute)) > f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, > now.month, > now.day, > now.hour, > now.minute)) > f.write("Category: {}\n".format(args.category)) > f.write("Slug: {}\n".format(slug)) > f.write("Authors: {}\n".format(args.author)) > f.write("Summary: \n") > > > if __name__ == "__main__": > Main() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic
On 30/03/18 03:48, Pat Martin wrote: > the "right" way to do it in python? More or less, a couple of comments below... > def Main(): Python function names begin with a lowercase letter by convention. > """Run if run as a program.""" > parser = argparse.ArgumentParser() ... > > now = datetime.datetime.now() > slug = args.title.replace(" ", "-").lower() > > with open("{}.md".format(slug), 'w') as f: > f.write("Title: {}\n".format(args.title)) > f.write("Date: {}-{}-{} {}:{}\n".format(now.year, > now.month, > now.day, > now.hour, > now.minute)) Formatting of dates and times is usually done using the time.strftime function which is specifically designed for that. It might be worth taking a peek at the docs on that one. You can call it directly on a datetime object - 'now' in your case: fmt="%Y-%m-%d %H:%M\n" f.write(now.strftime(fmt)) -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] pythonic
Hello all, I have written the following program. It generates a template for Pelican web site static generator. It works just fine, it generates the template and then I put the info in it to customize. But I was wondering, is this the "right" way to do it in python? #!/usr/bin/env python3 """Generate a Pelican markdown base page.""" import argparse import datetime def Main(): """Run if run as a program.""" parser = argparse.ArgumentParser() parser.add_argument("-T", "--title", type=str, required=True, help='Title for site, also generates the slug', metavar="") parser.add_argument("-c", "--category", required=True, help='Category or categories of post', metavar="") parser.add_argument("-t", "--tags", type=str, required=True, help="Tags for post", metavar="") parser.add_argument("-a", "--author", type=str, default="Pat Martin", help="Author of post", metavar="") args = parser.parse_args() now = datetime.datetime.now() slug = args.title.replace(" ", "-").lower() with open("{}.md".format(slug), 'w') as f: f.write("Title: {}\n".format(args.title)) f.write("Date: {}-{}-{} {}:{}\n".format(now.year, now.month, now.day, now.hour, now.minute)) f.write("Modified: {}-{}-{} {}:{}\n".format(now.year, now.month, now.day, now.hour, now.minute)) f.write("Category: {}\n".format(args.category)) f.write("Slug: {}\n".format(slug)) f.write("Authors: {}\n".format(args.author)) f.write("Summary: \n") if __name__ == "__main__": Main() Thanks for any input. WP ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic ascii decoding!
On Mon, Jul 31, 2017 at 3:39 PM, brucewrote: > > So, is there a quick/dirty approach I can use to simply strip out the > "non-ascii" chars. I know, this might not be the "best/pythonic" way, > and that it might result in loss of some data/chars, but I can live > with it for now. Ignore or replace the non-ASCII characters. For example: >>> print 's\xffp\xffa\xffm'.decode('ascii', 'ignore') spam >>> print 's\xffp\xffa\xffm'.decode('ascii', 'replace') s�p�a�m ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pythonic ascii decoding!
On 07/31/2017 09:39 AM, bruce wrote: > Hi guys. > > Testing getting data from a number of different US based/targeted > websites. So the input data source for the most part, will be "ascii". > I'm getting a few "weird" chars every now and then asn as fas as I can > tell, they should be utf-8. > > However, the following hasn;t always worked: > s=str(s).decode('utf-8').strip() > > So, is there a quick/dirty approach I can use to simply strip out the > "non-ascii" chars. I know, this might not be the "best/pythonic" way, > and that it might result in loss of some data/chars, but I can live > with it for now. > > thoughts/comments ?? It's easy enough to toss chars if you don't care what's being tossed, which sounds like your case, something like: ''.join(i for i in s if ord(i) < 128) but there's actually lots to think about here (I'm sure others will jump in) - Python2 strings default to ascii, Python3 to unicode, there may be some excitement with the use of ord() depending on how the string is passed around - websites will tell you their encoding, which you could and probably should make use of - web scraping with Python is a pretty well developed field, perhaps you might want to use one of the existing projects? (https://scrapy.org/ is pretty famous, certainly not the only one) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] pythonic ascii decoding!
Hi guys. Testing getting data from a number of different US based/targeted websites. So the input data source for the most part, will be "ascii". I'm getting a few "weird" chars every now and then asn as fas as I can tell, they should be utf-8. However, the following hasn;t always worked: s=str(s).decode('utf-8').strip() So, is there a quick/dirty approach I can use to simply strip out the "non-ascii" chars. I know, this might not be the "best/pythonic" way, and that it might result in loss of some data/chars, but I can live with it for now. thoughts/comments ?? thanks ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic review (descriptors)
On 28/04/15 10:55, Sage Hack wrote: I'm looking for somebody willing to review parts of this code https://github.com/SageHack/cloud-buster and let me know what is not Pythonic :P https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor The thing that jumps out to me is your use of class variables to hold a dictionary of instance responses based on the instance ID. That pattern looks like this, and you use it in every class: class SomeClass: classvar = {} def __init__(self,id): self.id = id def __get__(self...): v = getSomeValue() sel.classvar[self.id] = v Normally you'd store instance specific data in the instance itself not in a class variable. also you overwrite the classvariable entry for each instance every time you call the get(). Is that really what you want? The other thing is that you should have docstrings for both the classes and methods. Finally, and not Python specific, You have several classes sharing the same 'ID' data - self.domain - that's usually a bad OOP smell. Only one class should be mastering any given type of data, so maybe your other classes are really methods of whichever is the master class? Particularly since they don't have any explicit methods (also a bad OOP smell) of their own. -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic review (descriptors)
I'm looking for somebody willing to review parts of this code https://github.com/SageHack/cloud-buster and let me know what is not Pythonic :P I want to improve my Python coding skills but I'm not sure exactly what to study next. Right now I'm trying to use descriptors correctly and I'd like to know if this is about right https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor Thanks :) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic review (descriptors)
On 28/04/15 10:55, Sage Hack wrote: I'm looking for somebody willing to review parts of this code https://github.com/SageHack/cloud-buster and let me know what is not Pythonic :P https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor Another point re the PageTitle class: class PageTitle(object): titles = {} def __init__(self, url, host=None): self.url = url self.host = host def __get__(self, obj=None, objtype=None):... @property def id(self): if self.host: return self.url+':'+self.host else: return self.url There is not much point in calculating the id each time, it could simply be set in the init(). You never change the url or host. -- 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@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic way of concatenation of elements in an array
Hello, My code is - l = len(m) item = str(m[1]) for i in range(2,l): item = item + - + str(m[i]) This code is part of a bigger function. It works fine. But I am not happy with the way I have written it. I think there is a better (Pythonic) way to rewrite it. If anyone knows how to improve this snippet, I would be very thankful. Thanks and Regards, Sumod -- http://spawgi.wordpress.com We can do it and do it better. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way of concatenation of elements in an array
spa...@gmail.com wrote: Hello, My code is - l = len(m) item = str(m[1]) for i in range(2,l): item = item + - + str(m[i]) This code is part of a bigger function. It works fine. But I am not happy with the way I have written it. I think there is a better (Pythonic) way to rewrite it. If anyone knows how to improve this snippet, I would be very thankful. (1) Never use l as a variable name, as it looks too much like 1. (2) Use meaningful names. When posting snippets for help, you should show example data. (3) You almost never need to iterate over an index by hand. Instead iterate over the items themselves. That is, instead of this: for i in len(sequence): do_something_with( sequence[i] ) do this instead: for item in sequence: do_something_with( item ) and similar variations. (4) When you want only part of a sequence, use slicing to extract just the parts you care about. (5) When assembling strings from substrings, never use repeated concatenation using + as that can be EXTREMELY slow. Use str.join to build the string in one assignment, instead of multiple assignments. Your code shown above is *very* inefficient and will be PAINFULLY slow if m is very large. To understand why, you should read this article: http://www.joelonsoftware.com/articles/fog000319.html In this case, you can replace your snippet with this: result = '-'.join(str(item) for item in m[1:]) For example: py m = [1, 2, hello world, (23, 42), 5] py '-'.join(str(item) for item in m[1:]) '2-hello world-(23, 42)-5' -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way of concatenation of elements in an array
Hello Steven, Thanks a lot for the detailed answer. I will implement your suggestions. Really appreciate it. Thanks and Regards, Sumod On Fri, Jan 27, 2012 at 4:34 AM, Steven D'Aprano st...@pearwood.infowrote: spa...@gmail.com wrote: Hello, My code is - l = len(m) item = str(m[1]) for i in range(2,l): item = item + - + str(m[i]) This code is part of a bigger function. It works fine. But I am not happy with the way I have written it. I think there is a better (Pythonic) way to rewrite it. If anyone knows how to improve this snippet, I would be very thankful. (1) Never use l as a variable name, as it looks too much like 1. (2) Use meaningful names. When posting snippets for help, you should show example data. (3) You almost never need to iterate over an index by hand. Instead iterate over the items themselves. That is, instead of this: for i in len(sequence): do_something_with( sequence[i] ) do this instead: for item in sequence: do_something_with( item ) and similar variations. (4) When you want only part of a sequence, use slicing to extract just the parts you care about. (5) When assembling strings from substrings, never use repeated concatenation using + as that can be EXTREMELY slow. Use str.join to build the string in one assignment, instead of multiple assignments. Your code shown above is *very* inefficient and will be PAINFULLY slow if m is very large. To understand why, you should read this article: http://www.joelonsoftware.com/**articles/fog000319.htmlhttp://www.joelonsoftware.com/articles/fog000319.html In this case, you can replace your snippet with this: result = '-'.join(str(item) for item in m[1:]) For example: py m = [1, 2, hello world, (23, 42), 5] py '-'.join(str(item) for item in m[1:]) '2-hello world-(23, 42)-5' -- Steven __**_ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/**mailman/listinfo/tutorhttp://mail.python.org/mailman/listinfo/tutor -- http://spawgi.wordpress.com We can do it and do it better. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way of concatenation of elements in an array
Hi Steven, (5) When assembling strings from substrings, never use repeated concatenation using + as that can be EXTREMELY slow. Use str.join to build the string in one assignment, instead of multiple assignments. Your code shown above is *very* inefficient and will be PAINFULLY slow if m is very large. To understand why, you should read this article: http://www.joelonsoftware.com/articles/fog000319.html In this case, you can replace your snippet with this: result = '-'.join(str(item) for item in m[1:]) This was an interesting article. I have only had one programming class, and that was 15 years ago or so, so these are not issues I am aware of. I often find myself joining strings (and have mostly used + to do it). An alternate method I use is, for eg. print('here is a string %s which has many variables %s %s %s I have to sort out' %(s1,s2,s3,s4)) where the various strings (s1 - s4) have been determined elsewhere, perhaps in a loop. Is this method any better at combining strings than the +? My first guess would be no, but that is really just a guess. Thanks, Andre ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic nested lists
col speed ajarnco...@gmail.com wrote HI again, I realise that I should have included more information in the above e-mail. Here goes: a/ I have a 9*9 nested list called rows, which contains the given numbers in a sudoku puzzle - with 0s where the blanks go. b/ I create roworder (roworder = [[str(j)+str(i) for i in range(9)] for j in range(9)]) - [[00 -- 08], [10 -- 18] -- [80 -- 88]] c/ I populate a dictionary (dic) with keys from roworder and values from rows d/ I loop through the dict, changing any value0 to be set(range(1, 10))- a list of possible numbers. e/ Then I do: for i in roworder: notPoss = set([dic[j] for j in i if type(dic[j]) == int]) for k in j: if type(dic[k]) == set: dic[k].difference_update(notPoss) thus removing the numbers that exist in the row from the possible numbers I need to do this for the columns and squares aswell, which is why I do: That approach should work. Personally I'd probably create a Square class and bae my data on 9 squares. Each square can return a row(of 3 items) given an index and a column(of 3 items) given an index. class Square: def __init__(self, size=3): self.cells = [0 for n in range(size*size)] ... def __str__(self):... def getRow(self,n): ... def getCol(self,n):... def setCell(self,x,y,value) def check(self):... Thus I'd build my rows and columns dynamically from the squares rather than the other way round. It just feels more natural to me. But your approach should work too. However I confess I haven't studied you code in detail. Is there any specific problem or question you have or are you looking for general feedback? HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic nested lists
Message: 6 Date: Tue, 28 Sep 2010 13:15:26 +0700 From: col speed ajarnco...@gmail.com To: tutor@python.org Subject: [Tutor] Pythonic nested lists Message-ID: aanlktimdykbkzxaacbaagpq_faz50ruy=bcr81dqx...@mail.gmail.com Content-Type: text/plain; charset=iso-8859-1 Hi all, I've been trying to write a programme that solves sudoku problems for a while now. I'm getting close, but would like to ask a few questions about the most pythonic way of doing some things. I've decided to create nested lists (row order, column order and square order) which correspond with dictionary keys - the values of which are the numbers given in the puzzle - so I can loop through the dict in different orders. I think the first two are OK, but the square order list seems extremely messy and I would love some pointers. What I have is as follows: roworder = [[str(j)+str(i) for i in range(9)] for j in range(9)] colorder = zip(*roworder) #here comes the problem! start, index = 0,0 sqorder = [] for i in range(9): sqorder.append([]) for j in range(start, start+3): sqorder[i].extend(roworder[j][index:index+3]) if index == 6: index = 0 else: index += 3 if i == 2 or i == 5: start += 3 Any comments at all would be gratefully received. Thanks in advance Colin ___ HI again, I realise that I should have included more information in the above e-mail. Here goes: a/ I have a 9*9 nested list called rows, which contains the given numbers in a sudoku puzzle - with 0s where the blanks go. b/ I create roworder (roworder = [[str(j)+str(i) for i in range(9)] for j in range(9)]) - [[00 -- 08], [10 -- 18] -- [80 -- 88]] c/ I populate a dictionary (dic) with keys from roworder and values from rows d/ I loop through the dict, changing any value0 to be set(range(1, 10))- a list of possible numbers. e/ Then I do: for i in roworder: notPoss = set([dic[j] for j in i if type(dic[j]) == int]) for k in j: if type(dic[k]) == set: dic[k].difference_update(notPoss) thus removing the numbers that exist in the row from the possible numbers I need to do this for the columns and squares aswell, which is why I do: colorder = zip(*roworder) - (create a nested list column wise rather than row wise) and want to create a square order list - which is what the above mess does. I hope this clarifies things. Thanks again Colin ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic nested lists
Hi all, I've been trying to write a programme that solves sudoku problems for a while now. I'm getting close, but would like to ask a few questions about the most pythonic way of doing some things. I've decided to create nested lists (row order, column order and square order) which correspond with dictionary keys - the values of which are the numbers given in the puzzle - so I can loop through the dict in different orders. I think the first two are OK, but the square order list seems extremely messy and I would love some pointers. What I have is as follows: roworder = [[str(j)+str(i) for i in range(9)] for j in range(9)] colorder = zip(*roworder) #here comes the problem! start, index = 0,0 sqorder = [] for i in range(9): sqorder.append([]) for j in range(start, start+3): sqorder[i].extend(roworder[j][index:index+3]) if index == 6: index = 0 else: index += 3 if i == 2 or i == 5: start += 3 Any comments at all would be gratefully received. Thanks in advance Colin ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to normalize vertical whitespace
Le Fri, 08 May 2009 13:03:47 -0400, pyt...@bdurham.com s'exprima ainsi: [...] Approaches: 1. split text to list of lines that get stripped then: a. walk this list building a new list of lines that track and ignore extra blank lines -OR- b. re-join lines and replace '\n\n\n' wth' \n\n' until no more '\n\n\n' matches exist 2. use regular expressions to match and replace whitespace pattern of 3 or more adjacent \n's with surrounding whitespace 3. a 3rd party text processing library designed for efficiently cleaning up text Thanks! You should try 1a and 1b if only to have written the code at least once ;-) The set of python string methods is very complete and practicle. Still, in this case, 2 is rather straightforward and simple. If you cannot figure out the proper pattern, have a look at http://www.amk.ca/python/howto/regex/ and/or ask again the list. Denis -- la vita e estrany ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic way to normalize vertical whitespace
Note: Following cross-posted to python-list where it got queued due to suspicious subject line. I'm looking for suggestions on technique (not necessarily code) about the most pythonic way to normalize vertical whitespace in blocks of text so that there is never more than 1 blank line between paragraphs. Our source text has newlines normalized to single newlines (\n vs. combinations of \r and \n), but there may be leading and trailing whitespace around each newline. Approaches: 1. split text to list of lines that get stripped then: a. walk this list building a new list of lines that track and ignore extra blank lines -OR- b. re-join lines and replace '\n\n\n' wth' \n\n' until no more '\n\n\n' matches exist 2. use regular expressions to match and replace whitespace pattern of 3 or more adjacent \n's with surrounding whitespace 3. a 3rd party text processing library designed for efficiently cleaning up text Thanks! ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to normalize vertical whitespace
pyt...@bdurham.com wrote: Note: Following cross-posted to python-list where it got queued due to suspicious subject line. I'm looking for suggestions on technique (not necessarily code) about the most pythonic way to normalize vertical whitespace in blocks of text so that there is never more than 1 blank line between paragraphs. Our source text has newlines normalized to single newlines (\n vs. combinations of \r and \n), but there may be leading and trailing whitespace around each newline. I can't follow that! Please provide a before and after example. Approaches: 1. split text to list of lines that get stripped then: a. walk this list building a new list of lines that track and ignore extra blank lines -OR- b. re-join lines and replace '\n\n\n' wth' \n\n' until no more '\n\n\n' matches exist 2. use regular expressions to match and replace whitespace pattern of 3 or more adjacent \n's with surrounding whitespace 3. a 3rd party text processing library designed for efficiently cleaning up text Thanks! ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor -- Bob Gailer Chapel Hill NC 919-636-4239 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to normalize vertical whitespace
On Fri, May 8, 2009 at 1:03 PM, pyt...@bdurham.com wrote: Note: Following cross-posted to python-list where it got queued due to suspicious subject line. I'm looking for suggestions on technique (not necessarily code) about the most pythonic way to normalize vertical whitespace in blocks of text so that there is never more than 1 blank line between paragraphs. Our source text has newlines normalized to single newlines (\n vs. combinations of \r and \n), but there may be leading and trailing whitespace around each newline. Approaches: 1. split text to list of lines that get stripped then: a. walk this list building a new list of lines that track and ignore extra blank lines -OR- b. re-join lines and replace '\n\n\n' wth' \n\n' until no more '\n\n\n' matches exist 2. use regular expressions to match and replace whitespace pattern of 3 or more adjacent \n's with surrounding whitespace 3. a 3rd party text processing library designed for efficiently cleaning up text 1 sounds simple enough. That is the first thing I thought of. 2 should also be easy if you have any regex-fu and might turn out to be faster if you have a lot of text. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic way to extract delimited substrings
Suggestions on the best way to extract delimited substrings strings from a larger string? Background: I have a long multi-line string with expressions delimited with '(' and ')' markers. I would like to extract these substrings and process them in a loop. Because the left and right delimiters are different from each other *and* multi-char strings, it would appear that the .split() method would not be an appropriate tool for this work. I know how to do this task with regular expressions, but I'm always cautious about using a bazooka when a hammer will suffice. What strategy would you recommend? 1. Write a simple parsing function using string primitives (find, slicing) 2. Use regular expressions 3. Use a 3rd party string processing module Thanks! Malcolm ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to extract delimited substrings
Malcolm Greene wrote: Suggestions on the best way to extract delimited substrings strings from a larger string? Background: I have a long multi-line string with expressions delimited with '(' and ')' markers. I would like to extract these substrings and process them in a loop. What strategy would you recommend? If you just want to get the text between ( and ), re.findall() or re.finditer() is probably the simplest way to do it. If it is more complicated than that (e.g. nesting, escape chars) then I would probably look at pyparsing. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to extract delimited substrings
Malcolm Greene [EMAIL PROTECTED] wrote in Background: I have a long multi-line string with expressions delimited with '(' and ')' markers. I would like to extract these substrings and process them in a loop. I know how to do this task with regular expressions, but I'm always cautious about using a bazooka when a hammer will suffice. Sounds like an ideal candidate for regex and findall to me. If you have to stop a tank a bazooka may be the right tool... Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic way to try a few times, then raise exception?
Hello, I have a block of code buried deep in a module that I expect to fail periodically. (Calls to other machines over slow network, and such.) Generally, though, trying it a second / third will work. Is there clean way to write this on Python? Thanks __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to try a few times, then raise exception?
Allen Fowler [EMAIL PROTECTED] wrote I have a block of code buried deep in a module that I expect to fail periodically. (Calls to other machines over slow network, and such.) Generally, though, trying it a second / third will work. Is there clean way to write this on Python? There was a thread on this a few days ago but I can't find it now... In general if you only have a few (eg hundreds) things to check you can run a loop inside a loop and exit it with break if it works. Pdeudo code: for item in list: for attempt in range(3): result = accessItem(item) if result == OK: break else: sleep(T) # optional pause to regroup if needed... else: logError(item) But I'm not sure if that's what you count as clean! If the volumes being processed it is usually better to gather the failures up for seondary processing after getting through the successful ones. This is a much more efficient way of handling high data volumes. HTH -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic way to try a few times, then raise exception?
On Friday 26 October 2007 03:17:47 pm Alan Gauld wrote: Allen Fowler [EMAIL PROTECTED] wrote I have a block of code buried deep in a module that I expect to fail periodically. (Calls to other machines over slow network, and such.) Generally, though, trying it a second / third will work. Is there clean way to write this on Python? There was a thread on this a few days ago but I can't find it now... In general if you only have a few (eg hundreds) things to check you can run a loop inside a loop and exit it with break if it works. Pdeudo code: for item in list: for attempt in range(3): result = accessItem(item) if result == OK: break else: sleep(T) # optional pause to regroup if needed... else: logError(item) But I'm not sure if that's what you count as clean! If the volumes being processed it is usually better to gather the failures up for seondary processing after getting through the successful ones. This is a much more efficient way of handling high data volumes. HTH What about placing the try in a function and call the function from a loop passing the variable to check (computer name). Then each failure will not cause the app to stop processing. Use a counter in the calling procedure to the number of attempts. -- John Fabiani ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Pythonic? Building a full path from a visual file tree
Hey all, I would like to expand the visual representation of a tree hierarchy, given below, where child-ness is defined by indentation, and folder-ness is highlighted with a trailing '/' Input (test.txt): dir1/ file1 file2 1-1/ file3 file4 dir2/ file5 The desired output is a fully qualified path for each input line: dir1/ dir1/file1 dir1/file2 dir1/1-1/ dir1/1-1/file3 dir1/1-1/file4 dir2/ dir2/file5 I considered several brute-force solutions, but I persevered and came to, what I think, is a more Pythonic solution. What do you think? import string def expand_tree(filetree): indent = '\t' stack = [] for f in filetree: indents = f.count(indent) while len(stack) indents: stack.pop() stack.append(f.strip()) yield string.join(stack,'') if not f.endswith('/'): stack.pop() lines = [line.rstrip() for line in file('test.txt')] for i in expand_tree(lines): print i Those familiar with subversion (particularly, svnlook tree /path/to/repos) may recognize the problem space and the sample input (except that I simplified things a bit here, using a tab to indicate level-of-hierarchy instead of a single space, which could appear in the filename). The real-world solution will use a regex to find run of spaces at the start of element 'f'. It will also get input from stdin instead of a file. Questions: Is the list comprehension the right idiom for getting a file into a list, without the EOL chars? I'm hard-pressed to see how it could be more concise, but this is Python :) and the rtrim() feels a little off. Is string.join() preferred to ''.join? Does importing all of string outweigh the readability of string.join()? Any subversion geeks know of way to eliminate this code with a native svn command? Did other folks choke on generators for as long as I did? I'm not going to admit, publicly, how long that was :) But I found this little test illustrative: def gen(): yield 1 yield 2 yield 3 g = gen() g.next() 1 g.next() 2 g.next() 3 g.next() [stack trace] Beyond simple, but the obviousness of it is hidden in many of the examples I saw. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic? Building a full path from a visual file tree
stv wrote: I considered several brute-force solutions, but I persevered and came to, what I think, is a more Pythonic solution. What do you think? Looks pretty sweet to me :-) import string def expand_tree(filetree): indent = '\t' stack = [] for f in filetree: indents = f.count(indent) while len(stack) indents: stack.pop() stack.append(f.strip()) yield string.join(stack,'') if not f.endswith('/'): stack.pop() lines = [line.rstrip() for line in file('test.txt')] for i in expand_tree(lines): print i Questions: Is the list comprehension the right idiom for getting a file into a list, without the EOL chars? I'm hard-pressed to see how it could be more concise, but this is Python :) and the rtrim() feels a little off. The list comp is fine but I don't think you need it at all, since you strip() the string before you add it to stack. Is string.join() preferred to ''.join? Does importing all of string outweigh the readability of string.join()? string.join() is deprecated, ''.join() is preferred. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic? Building a full path from a visual file tree
The list comp is fine but I don't think you need it at all, since you strip() the string before you add it to stack. Ahh yes. I used the rstrip() in development, printing intermediary output to stdout, so I could see what my input file-to-list looked like (and it looked ugly with all those EOLs). The strip() to the stack is there primarily to remove the indentation but, of course, it can do double duty. string.join() is deprecated, ''.join() is preferred. Well, I'll live with it ;-) fugly as it looks. I'm really finding that Python nudges me into pleasant code. Doing the above in somthing like VB, I would just brute-force it and it would feel right. Brute forcing it in Python ... well, it just feels wrong ... Thanks for the input. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic? Building a full path from a visual file tree
On 3/21/06, stv [EMAIL PROTECTED] wrote: import string def expand_tree(filetree): indent = '\t' stack = [] for f in filetree: indents = f.count(indent) while len(stack) indents: stack.pop() stack.append(f.strip()) yield string.join(stack,'') if not f.endswith('/'): stack.pop() The real-world solution will use a regex to find run of spaces at the start of element 'f'. Hmmm, I'm having to rethink this ... regex will probably not do what I want (count instance of indent ... or, even if regex will do, there's probably a cleaner solution without it. Given the subversion problem space (where I can count on 1 space for each level of child-ness), are there cleaner solutions than this: indents = len(f) - len(f.lstrip()) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor