Re: [Tutor] improvements on a renaming script
On 09Mar2014 15:22, street.swee...@mailworks.org wrote: > A bit of background, I had some slides scanned and a 3-character > slice of the file name indicates what roll of film it was. > This is recorded in a tab-separated file called fileNames.tab. > Its content looks something like: > > p01 200511_autumn_leaves > p02 200603_apple_plum_cherry_blossoms > > The original file names looked like: > > 1p01_abc_0001.jpg > 1p02_abc_0005.jpg > > The renamed files are: > > 200511_autumn_leaves_-_001.jpeg > 200603_apple_plum_cherry_blossoms_-_005.jpeg > > The script below works and has done what I wanted, but I have a > few questions: > > - In the get_long_names() function, the for/if thing is reading > the whole fileNames.tab file every time, isn't it? In reality, > the file was only a few dozen lines long, so I suppose it doesn't > matter, but is there a better way to do this? Read it once, into a dictionary. I'd rename "get_long_name" to "get_long_names", and have it create and return a dictionary with keys being the glnAbbrev value and values being the long name. So start with: long_names = {} Fill it out by saving the abbrev and long_name for each row, and return "long_names" at the end of the function. Then call it once at the start of your program, and then just look things up directly in the dictionary instead of calling "get_long_name()". > - Really, I wanted to create a new sequence number at the end of > each file name, but I thought this would be difficult. In order > for it to count from 01 to whatever the last file is per set p01, > p02, etc, it would have to be aware of the set name and how many > files are in it. So I settled for getting the last 3 digits of > the original file name using splitext(). The strings were unique, > so it worked out. However, I can see this being useful in other > places, so I was wondering if there is a good way to do this. > Is there a term or phrase I can search on? Nothing specific comes to mind. When I do this kind of thing I tend to make an opening pass over os.listdir() pulling out all the names and noting whatever is relevant. In your case you might maintain a dictionary of the "base" filename key (i.e. the filename without the trailing sequence number) and the maximum sequence number seen for that file. Then I'd have a short function which was passed this dictionary and a "base" filename, and returned a new sequence number, being the first sequence number after the current maximum from the dictionary for which the constructed new filename did not exist. Then update the number in the dictionary, probably inside that function. > - I'd be interested to read any other comments on the code. > I'm new to python and I have only a bit of computer science study, > quite some time ago. My personal habit is to put the main program logic at the top. I know you can't just move it because you rely on functions when must be defined first. However, you can do this: def main(argv): ... main program logic here ... return and put: sys.exit(main(sys.argv)) at the bottom of the program. This has the advantage of having the main program logic at the top where it is easy to find. > # rename > for f in os.listdir(indir): > if f.endswith(".jpg"): > os.rename( > os.path.join(indir,f),os.path.join( > outdir, > > get_long_name(get_slice(f))+"_-_"+get_bn_seq(f)+".jpeg") > ) I'd preceed the rename() by computing: oldname = os.path.join(indir,f) newname = ( os.path.join(outdir, get_long_name(get_slice(f)) + "_-_" + get_bn_seq(f) + ".jpeg" ) and just pass oldname, newname to os.rename(). Easily to read and debug. Cheers, -- Cameron Simpson Patriotism means to stand by the country. It does not mean to stand by the President. - Theodore Roosevelt ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] improvements on a renaming script
On 09Mar2014 22:50, bob gailer wrote: > Beware using tabs as indents. As rendered by Thunderbird they appear > as 8 spaces which is IMHO overkill. > It is much better to use spaces. Most Python IDEs have an option to > convert tabs to spaces. Further to this remark, this isn't an instruction to not use the TAB key. It is advice to get your editor to fill in the program text with the necessary number of spaces instead of inserting a literal TAB character. (But if you can't tell your editor to do this, then avoid the TAB key; use the space bar.) > The Python recommendation is 4; I use 2. Me too. But not in code I give to other projects; there the rule is "use their coding standard", and that is usually 4 spaces per indent for Python projects. As an example, I use vi/vim and have this in my config: set expandtab set shiftwidth=2 set tabstop=8 The expandtab tells vim to insert spaces instead of a TAB character. The shiftwidth reflects my 2 space indent preference. The tabstop reflects the expectation that interpretation of the tab keystroke and of any literal TABs in the text expects them to indicate an 8-column TAB convention. Note that many users set their tabstop equivalent to 4 or whatever their preferrer indentation depth is. This is why it is some important and useful to get your editor to insert spaces: whatever your personal tabstop setting, the program text will be correctly rendered for others because it will not contain TAB character, it will contain spaces. Cheers, -- Cameron Simpson Wirth's Law: Software is getting slower more rapidly than hardware becomes faster. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On Mar 8, 2014, at 7:29 AM, eryksun wrote: > i.e. > >guess < 1 or guess > 100 > > becomes > >not not (guess < 1 or guess > 100) Why a not not? Wouldn’t that just be saying do this because the second not is undoing the first? > > distribute over the disjunction > >not (not (guess < 1) and not (guess > 100)) > > logically negate the comparisons > >not (1 <= guess and guess <= 100) > > finally, write the conjoined comparisons as a chained comparison: > >not (1 <= guess <= 100) > > i.e., guess isn't in the closed interval [1, 100]. > > Anyway, you needn't go out of your way to rewrite the expression using > a chained comparison. The disjunctive expression is actually > implemented more efficiently by CPython's compiler, which you can > verify using the dis module to disassemble the bytecode. I’m not sure what you’re talking about in the above paragraph. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On Mar 8, 2014, at 7:35 AM, Mark Lawrence wrote: > > I have no interest in the efficiency, only what is easiest for me to read, > which in this case is the chained comparison. As a rule of thumb I'd also > prefer it to be logically correct :) > What exactly is ment by a chained comparison? Wouldn’t what I wrote be chained? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 10/03/2014 02:05, Scott W Dunning wrote: On Mar 8, 2014, at 7:35 AM, Mark Lawrence wrote: I have no interest in the efficiency, only what is easiest for me to read, which in this case is the chained comparison. As a rule of thumb I'd also prefer it to be logically correct :) What exactly is ment by a chained comparison? Wouldn’t what I wrote be chained? A chained comparison refers to the fact that the comparison can be written without using and or or, see http://docs.python.org/3/reference/expressions.html, not the if/elif chain. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 10/03/2014 02:03, Scott W Dunning wrote: On Mar 8, 2014, at 7:29 AM, eryksun wrote: Anyway, you needn't go out of your way to rewrite the expression using a chained comparison. The disjunctive expression is actually implemented more efficiently by CPython's compiler, which you can verify using the dis module to disassemble the bytecode. I’m not sure what you’re talking about in the above paragraph. As a newbie don't worry about it (yet). Personally I think it's plain daft to put such advanced language topics on a tutor mailing list. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On Mon, Mar 10, 2014 at 5:29 AM, Mark Lawrence wrote: > > As a newbie don't worry about it (yet). Personally I think it's plain daft > to put such advanced language topics on a tutor mailing list. Different strokes for different folks. I like to tinker with and disassemble things as I'm learning about them. I would have been ecstatic about open source as a kid. I learn simultaneously from the top down and bottom up -- outside to inside and inside to outside. I need an abstract overview (a map) combined with a concrete realization. Tell me and show me -- and let me tinker and experiment. If learning isn't fun, I'm not learning. The Python language reference, while being far more accessible than an ISO standard or technical report, is still an abstract, highly verbal specification. I understand it, but I don't truly 'grok' a lot of things until I see how it's implemented in bytecode, or even down to the C source level. Putting the two together, I meet in the middle with a better understanding of how it works. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] improvements on a renaming script
On Sun, Mar 09, 2014 at 03:22:35PM -0400, street.swee...@mailworks.org wrote: > - In the get_long_names() function, the for/if thing is reading > the whole fileNames.tab file every time, isn't it? In reality, > the file was only a few dozen lines long, so I suppose it doesn't > matter, but is there a better way to do this? Yes, read the file once and build a dictionary mapping the first column to the second column. > - Really, I wanted to create a new sequence number at the end of > each file name, but I thought this would be difficult. In order > for it to count from 01 to whatever the last file is per set p01, > p02, etc, it would have to be aware of the set name and how many > files are in it. So I settled for getting the last 3 digits of > the original file name using splitext(). The strings were unique, > so it worked out. However, I can see this being useful in other > places, so I was wondering if there is a good way to do this. > Is there a term or phrase I can search on? Buckets? You'll need a function to differentiate the files into the desired groups(buckets). You can use that function to generate a dictionary mapping a bucket name to a list of files(the bucket). Iterate over all the files, sorting them into buckets. Then iterate over the buckets, increasing the counter every file, and reseting the counter in between buckets. Here's how I'd do it for your script: def get_bucket_key(filename): prefix = filename.split('_')[0] return prefix def sort_files_into_buckets(file_list): buckets_to_files = {} for filename in file_list: key = get_bucket_key(filename) if key in buckets_to_files: buckets_to_files[key].append(filename) else: buckets_to_files[key] = [filename] return buckets_to_files file_list = os.listdir(...) buckets_to_files = sort_files_into_buckets(file_list) for (bucket_key, bucket_file_list) in buckets_to_files.items(): counter = 1 for file in bucket_file_list: print "{0}_{1}.jpg".format(bucket_key, counter) counter += 1 > - I'd be interested to read any other comments on the code. > I'm new to python and I have only a bit of computer science study, > quite some time ago. You should read PEP8[http://legacy.python.org/dev/peps/pep-0008/] for the basic Python style guide. If you'll be writing things to share or come back to after a while, it would be good to learn about documentation, start by reading PEP257[http://legacy.python.org/dev/peps/pep-0257/]. Note that I've written my own versions alongside my comments. I'm not sure if that's OK on this mailing list, and if you want a spoiler-free version with just the commentary and no code let me know and I'll resend it: > # get longnames from fileNames.tab > def get_long_name(glnAbbrev): Don't be afraid to use longer function/argument names and skip the comment, your code will end up much more readable. Does the "gln" in "glnAbbrev" stand for "get_long_name"? It seems repetitive to include the name of the function in the name of it's parameters. And I think we're passing the function a prefix, not an abbreviation: def get_long_names_from_file(prefix): > with open( > os.path.join(os.path.expanduser('~'),'temp2','fileNames.tab') > ) as filenames: Good, pythonic usage of context managers but it took a second longer to click than splitting it out into 2 lines. Also you should add spaces after each parameter in a function call: filenames_path = os.path.join(os.path.expanduser('~'), 'temp2', 'fileNames.tab') with open(filenames_path) as input_file: > filenamesdata = csv.reader(filenames, delimiter='\t') > for row in filenamesdata: > if row[0] == glnAbbrev: > return row[1] This is where you would build a dictionary. You could skip the csv module and just iterate through the file, splitting each line to get the prefix and long_name. The split() function splits a string into a list of strings. If every line in this file has only 2 columns, we can unpack the list directly into 2 variables. I usually name my dictionary variables "key_to_value": prefix_to_long_name = {} for line in input_file: prefix, long_name = line.split() prefix_to_long_name[prefix] = long_name return prefix_to_long_name This could also be done by dictionary comprehensions: return {prefix: long_name for (prefix, long_name) in (line.split() for line in input_file)} Then just return your finished dictionary. Note that since we return a dictionary instead of searching for a specific prefix, we do not need our "prefix" parameter: def get_long_names_from_file(): But this sounds like we are returning a list of long_names, not a dictionary so I would rename it again to: def get_prefix_to_long_name_from_file() > # find shortname from slice in picture filename > def get_slice(fn): > threeColSlice = fn[1:4] > return threeC
Re: [Tutor] help me
hi I need your help plz with this cods ( I want u to tell wht cod I miss to stop the while loop whene I get 3 stars) rm = [] stars = 0 ##if stars == "3": ## print " You win" ##else: ## print "hh" def ask_yes_no(question): """Ask a yes or no question.""" answer = None while answer not in ("y", "n"): answer = raw_input(question).lower() return answer def congrate_winner(stars = "3"): print "congradulation you have.", stars, " stars you won!\n" return stars ##def stars(): ## #stars = 0 ## global stars ## stars = stars + 1 ## print "stars:", stars, "\n" ## ## if stars == "3": ## print "congadulation you win" ## else: ## print "Go to the next room" ## return stars def rest_room(): restroom = ["shower", "sink"] print restroom global stars ans = ask_yes_no("It does star ther?: ") print "This is the value of ans.", ans if ans == "y": print "\nOK" stars = stars + 1 print "Stars:", stars, "\n\n" else: print "hmm go to another room." print "Stars:", stars, "\n\n" return ans, restroom def living_room(): livingroom = ["uyyg", "hfgfd", "star"] print livingroom global stars ans = ask_yes_no("It does star ther?: ") print "Your answe is.", ans if ans == "y": print "\nOK" stars = stars + 1 print "Stars:", stars, "\n\n" else: print "hmm go to another room." print "Stars:", stars, "\n\n" return ans, livingroom def bed_room(): bedroom = ["iuyg", "star"] print bedroom global stars ans = ask_yes_no("It does star ther?: ") print "Your answe is.", ans if ans == "y": print "\nOK" stars = stars + 1 print "Stars:", stars, "\n\n" else: print "hmm go to another room." print "Stars:", stars, "\n\n" return ans, bedroom def Kichen(): kichen = ["star", "jyhffd"] global stars print kichen ans = ask_yes_no("It does star ther?: ") print "Your answe is.", ans if ans == "y": print "\nOK" stars = stars + 1 print "Stars:", stars, "\n\n" else: print "hmm go to another room." print "Stars:", stars, "\n\n" return ans, kichen def main(): print "Wlecome to my house." rm = None while rm != stars: print\ """ 0 - Northe 1 - South 2 - East 3 - Weast """ rm = raw_input("What room you want to go?: ") if rm == "0": rest_room() elif rm == "1": living_room() elif rm == "2": bed_room() elif rm == "3": Kichen() ##if stars == "3": ## congrate_winner() main() raw_input("\nPress the enter key to exit.") On Saturday, February 1, 2014 6:40 PM, hind fathallah wrote: thank you so much because I got it :) On Saturday, February 1, 2014 1:28 PM, Danny Yoo wrote: On Fri, Jan 31, 2014 at 8:55 PM, hind fathallah wrote: > hi can you answer this question for me plz [question omitted] Many of us probably could answer this. But this is not a homework-answering mailing list. The problem itself is not interesting to us. What is interesting is why the problem is giving you trouble. We'd rather focus on where you are having difficulty: we'd rather help *you*. Tell us what you've tried, where you're getting stuck, what other kinds of problems you've done that are similar to this one. That is, show us what general problem solving strategies you're using now. Maybe some of those strategies are not working for you.___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] help me
hind fathallah Wrote in message: > > > while rm != stars:     print\     """     0 - Northe     1 - South     2 - East     3 - Weast     """     rm = raw_input("What room you want to go?: ") Why are you looping till he gets to the weast room? Why not loop till stars reaches 3? -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] help me
hind fathallah wrote: > hi I need your help plz with this cods ( I want u to tell wht cod I miss > to stop the while loop whene I get 3 stars) rm = [] I think you are comparing a string and an integer. That gives False even if the values look the same: >>> i = 3 >>> s = "3" >>> print i, s 3 3 >>> i == s False Use repr() debug the problem: >>> print repr(i), repr(s) 3 '3' ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On Mar 10, 2014, at 4:15 AM, eryksun wrote: > > Different strokes for different folks. I like to tinker with and > disassemble things as I'm learning about them. I would have been > ecstatic about open source as a kid. I learn simultaneously from the > top down and bottom up -- outside to inside and inside to outside. I > need an abstract overview (a map) combined with a concrete > realization. Tell me and show me -- and let me tinker and experiment. > If learning isn't fun, I'm not learning. I agree I learn the same way. I just didn’t understand what you were saying. What exactly is Cpython? Is it different from the python I’m using? Also, what did you mean by; >> The disjunctive expression is actually >> implemented more efficiently by CPython's compiler, which you can >> verify using the dis module to disassemble the bytecode. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Python implementations (was: Help with Guess the number script)
Scott W Dunning writes: > What exactly is Cpython? Python is a language, with numerous implementations. CPython is one of those implementations. See https://wiki.python.org/moin/PythonImplementations> for an overview. > Is it different from the python I’m using? I don't know; how did you acquire the Python implementation you're using now? What does the Python interactive prompt display when you first launch an interactive Python shell? Note that the answer is likely to be “Yes, you are using some version of CPython” since that is the most common implementation. -- \“There are no significant bugs in our released software that | `\ any significant number of users want fixed.” —Bill Gates, | _o__) 1995-10-23 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
>> On Mar 8, 2014, at 3:57 AM, spir wrote: >>> >>> Well done. >>> And now that you have the right set of tests you can >>> half the number of lines by combining your if >>> conditions again, like you had in the original >>> post. ie. Bring your hot/cold/warm tests together. So below is what I finally came up with that works. I’m trying to condense it to half the number of lines like Denis suggested. I was hoping to clarify a couple things if you guys don’t mind…. I wanna make sure I understand how this code is working. So, from what I gather it first checks to see if the ‘guess’ is out of range and if that is false it continues to the next ‘if’ statement checking wether it’s too low. Now this is where I’m not 100% sure if the too low ‘if’ statement is false does it skip everything that is nested below it (you are cold, warm, on fire) and go to the ‘if statement checking if it’s too high? And now say the too low ‘if’ statement is true, because it’s an ‘if’ the code does not stop it continues but when it gets to the elif the code stops? def print_hints(secret, guess): if guess < 1 or guess > 100: print print "Out of range!" print if guess < secret: print print "Too low!" if guess < secret - 10: print "You are cold!" print print "Sorry please try again." print print elif guess < secret - 5: print "You are warmer!" print print "Sorry please try again." print print else: print "You're on fire!!" print print "Sorry please try again." print print if guess > secret: print print "Too high!" if guess > secret + 10: print "You are cold!" print print "Sorry please try again." print print elif guess > secret + 5: print "You are warmer!" print print "Sorry please try again." print print else: print "You're on fire!!" print print "Sorry please try again." print print This is what I have right now, obviously it’s not working. I’ve been playing around with it but I’m just not seeing where I’m going wrong. Any suggestions are greatly appreciated! def print_hints(secret, guess): if guess < 1 or guess > 100: print print "Out of range!" print if guess < secret: print print "Too low!" if guess > secret: print print "Too high!" if guess < secret - 10 or guess > secret - 10: print "You are cold!" print print "Sorry please try again." print print elif guess < secret - 5 or guess > secret - 5: print "You are warmer!" print print "Sorry please try again." print print else: print "You're on fire!!" print print "Sorry please try again." print print ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python implementations (was: Help with Guess the number script)
On Mar 10, 2014, at 8:52 PM, Ben Finney wrote: > > What does the Python interactive prompt display when you first launch an > interactive Python shell? Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "copyright", "credits" or "license()" for more information. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python implementations (was: Help with Guess the number script)
On Mar 10, 2014, at 8:52 PM, Ben Finney wrote: > > What does the Python interactive prompt display when you first launch an > interactive Python shell? Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "copyright", "credits" or "license()" for more information. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python implementations
Scott W Dunning writes: > On Mar 10, 2014, at 8:52 PM, Ben Finney wrote: > > > > What does the Python interactive prompt display when you first launch an > > interactive Python shell? > > Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) > [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin > Type "copyright", "credits" or "license()" for more information. Thanks. Yes, the clue is in the “[GCC …]”, which tells us the program was built using that version of GCC, the GNU Compiler Collection. This means it is implemented in the C programming language and is thus CPython. Because Python implementations all follow the Python language specification, this doesn't imply anything much for you as a user. Regardless of which implementation you're using, you're still using Python and have access to everything the documentation describes. This is useful to know, though, when you learn about some of the more peripheral capabilities present in one but not other implementations. But all that can wait. -- \ “I like my dental hygenist, I think she's very pretty; so when | `\I go to have my teeth cleaned, while I'm in the waiting room I | _o__)eat an entire box of cookies.” —Steven Wright | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On Mar 8, 2014, at 11:50 AM, Scott dunning wrote: >>> >>> And now that you have the right set of tests you can >>> half the number of lines by combining your if >>> conditions again, like you had in the original >>> post. ie. Bring your hot/cold/warm tests together. I’m having a hard time doing that because the guess can be either too low or too high but it is always either cold, warm, or on fire. I can’t figure out how to make it work with out splitting the cold, warm and on fire under two branches, one too low and one too high. Any suggestions? Thanks! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
Scott W Dunning Wrote in message: > Would you please stop posting in html? > def print_hints(secret, guess):   if guess < 1 or guess > 100:     print     print "Out of range!"     print   if guess < secret:     print     print "Too low!"   if guess > secret:     print     print "Too high!"   if guess < secret - 10 or guess > secret - 10: Think about that line. You might even want to put in a separate function to test what it does. HINT: it's wrong.     print "You are cold!"     print     print "Sorry please try again."     print     print   elif guess < secret - 5 or guess > secret - 5: Same mistake.     print "You are warmer!"     print     print "Sorry please try again."     print     print   else:     print "You're on fire!!"     print     print "Sorry please try again."     print     print -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor