I’ve gotten a few more exercises done today. I also finally understand why lists were giving me so much trouble! I couldn’t figure out why slicing lists took one more entry than I thought it should, but upon a more careful reading of Hetland, I found this explanation that totally cleared things up for me:
[T]he first limit (the leftmost) is … inclusive, while the second (the rightmost) is exclusive. When using a negative step size, you have to have a first limit (start index) that is higher than the second one.
This really cleared up why
date.py worked the way it did! I really was only selecting the appropriate numbers in MM/DD/YYYY format, I just didn’t understand why it appeared that I was selecting one more entry in list sequence than was necessary. Anyway, date.py got another revision that uses a
str(int(DD)) function to strip the leading zero from a date that had a single-digit day (10/01/2010 was coming out “October 01st, 2010”). Here is
#!/usr/bin/python # date.py v1.1.1 # 21 Aug 2010 # My second program # Date conversion tool # Changelog: # v1.1.1 - Correctly handles single-digit DD # v1.1 - Changed to be a MM/DD/YYYY converter # v1.0 - Convert numbers to American-style dates # user instructions print 'Convert MM/DD/YYYY dates to \"January 1st, 2010\" style.' # month list month_list = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] # sets suffixes for 31 days as 1st, 2nd, 3rd, 4th ... 20th, 21st, etc. day_suffix = ['st','nd','rd'] + 17*['th'] \ + ['st','nd','rd'] \ + 7*['th'] + ['st'] # get user input mmddyyyy = raw_input('Enter date in MM/DD/YYYY format: ') # divides user input into strings month_str = mmddyyyy[0:2] day_str = str(int(mmddyyyy[3:5])) year_str = mmddyyyy[6:10] # format user input month_name = month_list[int(month_str)-1] day_ordinal = day_str + day_suffix[int(day_str)-1] # print results onscreen print 'Your date is: ' + month_name + ' ' + day_ordinal + ', ' + year_str raw_input('Press <enter> to exit...')
I also wrote a very short, very simple script that strips the domain name from a URL. I’m not certain that it has any real-world use — in fact, even for testing it’s very limited in it’s ability. I just wanted to test my understanding of lists, otherwise I would have skipped the exercise entirely. Regardless, you may now behold
#!/usr/bin/env python # domainname.py v1.0.0 # 21 Aug 2010 # Extracts domain name from a URL # Changelog: # v.1.0.0 - Extract domain name from a URL url = raw_input ('Please enter a URL (e.g., "http://www.yahoo.com": ') domain = url[11:-4] print 'Domain name of the URL you entered: ' + domain raw_input ('Press <enter> to exit.')
You can download
domainname.v1-0-0.py from my Dropbox, too. I may come back to it and spice it up a bit, but more likely I’ll go back to date.py if I want to put more complex concepts to use. Maybe.
Also, as a grand finale, I tried really hard to do this one entirely by hand, but I had to look at the example because Hetland never said anything about the
len() function until he used it in the example 👿 . However, once I saw that, I got the rest working in short order. Yeah, it looks a lot like the book’s answer (as do pretty much all my code examples thus far), but I did everything by hand except the
len() thing. I even have a working way to have the user choose the width of his terminal, but I commented it out and just chose 80 as the default width because I hated typing ’80’ every time I tested the script 😛 . Here is
#!/usr/bin/env python # quotationbox.py v1.0.0 # 21 Aug 2010 # Take user-supplied quotation and make a centered ASCII box around it # Changelog: # v1.0.0 - Take user input and make a centered ASCII box around it # Get user's terminal width and quotation term_width = 80 # int(raw_input ('What is your terminal width? (Usually 80): ')) quotation = raw_input ('Enter your quotation here: ') # Determine width of quotation and box accordingly text_width = len(quotation) qbox_width = text_width + 2 margin_left = (term_width - qbox_width) // 2 print print ' ' * margin_left + '+' + '-' * qbox_width + '+' print ' ' * margin_left + '| ' + ' ' * text_width + ' |' print ' ' * margin_left + '| ' + quotation + ' |' print ' ' * margin_left + '| ' + ' ' * text_width + ' |' print ' ' * margin_left + '+' + '-' * qbox_width + '+' print raw_input ('Press <enter> to exit.')
And yeah, you can download quotationbox.v1-0-0.py from my Dropbox. At some point I want to soup up quotationbox and make v2.0 kinda like cowsay (which is my favorite part of the Linux Mint default terminal settings) and have a better-looking box that can handle multiple lines.
As you can see, I’ve decided to go with a “version x.y.z” naming method for all my scripts and to keep a changelog for each file as well. Yeah, it makes the files bigger, and complicates running them from the terminal a bit, but I’d rather know at a glance what changes I made and when without having to browse the code itself (or go back and read my own blog entries!) than have slightly smaller file size.
So yeah, I’ve been a busy fella today. Maybe not very fast, but pretty busy. I’m slowly learning how to think my way through problems. Python is really fun to learn, and I’m excited to learn more functions so I can make cooler, better, and more powerful programs!
UPDATE: Added screenshots.