943,563 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Unsolved
  • Views: 1093
  • Python RSS
Mar 1st, 2008
0

My first Python program, constructive critisism anyone?

Expand Post »
Well,

I've been programming for all of about 5 hours in Python now. From first opening my browser and googling the term to making this post here. I've written something up too! It's a short script that accepts input from the user about their date of birth and just prints some statistics about it. Such as their age in days/months/years.

It has some basic error checking though it's nothing serious like checking whether or not the DAY part of the DATE is possible in that MONTH (i.e. so you can get the 31st of February and it will accept it). Though it does make sure you don't make a 13th month.

Please take a look and I'm particularly interested if anyone can tell me alternate ways of doing things that I've done, especially if it's more efficient (or just generally better).

Thanks in advance.

python Syntax (Toggle Plain Text)
  1. # Filename: age2.py
  2. # Author: Mark Williams
  3.  
  4. #Do all the module imports first
  5. import datetime
  6.  
  7. #Just a Def to all up to convert strings to UPPERCASE
  8. def to_upper(string):
  9. upper_case = ""
  10. for character in string:
  11. if 'a' <= character <= 'z':
  12. location = ord(character) - ord('a')
  13. new_ascii = location + ord('A')
  14. character = chr(new_ascii)
  15. upper_case = upper_case + character
  16. return upper_case
  17. #End of Def here.
  18.  
  19. #Next we'll import the date from that module we loaded.
  20. from datetime import date
  21.  
  22. #And put the date today in a variable
  23. now = date.today()
  24.  
  25. #Then we'll make a seperate variable for each 'piece'
  26. #of the date for manipulation
  27.  
  28. #Yeah, YEAR input now with error checking
  29. error_var = 0
  30. while error_var == 0:
  31. y = int(raw_input('Please enter the YEAR of which you were born: '))
  32. if y >= 2009:
  33. print "Error, you're not born yet! Try again."
  34. elif y < 0:
  35. print "Error, no way we're you born BC!"
  36. else:
  37. error_var = 1
  38.  
  39. #Next is Month input with error checking for both integer input
  40. #and for string input.
  41. error_val = 0
  42. while error_val == 0:
  43. m = raw_input('Please enter the MONTH of which you were born: ')
  44. try:
  45. dummy = int(m)
  46. #error checking on the input number (as it was given as an integer)
  47. m = int (m)
  48. if m < 1 or m > 12:
  49. print "Error? That's not a month!"
  50. else:
  51. error_val = 1
  52. except:
  53. m = to_upper(m)[:3]
  54. #Convert the string version to an integer version
  55. #Lots of "error_val..." here, might take a look at
  56. #removing these somehow.
  57. if m == "JAN":
  58. m = 1
  59. elif m == "FEB":
  60. m = 2
  61. error_val = 1
  62. elif m == "MAR":
  63. m = 3
  64. error_val = 1
  65. elif m == "APR":
  66. m = 4
  67. error_val = 1
  68. elif m == "MAY":
  69. m = 5
  70. error_val = 1
  71. elif m == "JUN":
  72. m = 6
  73. error_val = 1
  74. elif m == "JUL":
  75. m = 7
  76. error_val = 1
  77. elif m == "AUG":
  78. m = 8
  79. error_val = 1
  80. elif m == "SEP":
  81. m = 9
  82. error_val = 1
  83. elif m == "OCT":
  84. m = 10
  85. error_val = 1
  86. elif m == "NOV":
  87. m = 11
  88. error_val = 1
  89. elif m == "DEC":
  90. m = 12
  91. error_val = 1
  92. else:
  93. print "\nError, didn't get which month you meant there either \n\
  94. enter it as an integer (1 to 12) or type the month name out, \n\
  95. either as an abbreviation (Jan, Feb, Mar...) or in \n\
  96. full (January, February...)\n"
  97.  
  98. #Day input, again with error checking
  99. error_var = 0
  100. while error_var == 0:
  101. d = int(raw_input('Please enter the DAY on which you were born: '))
  102. if d < 1 or d > 32:
  103. print "Error, what DAY did you say?"
  104. else:
  105. error_var = 1
  106.  
  107. #Added here so as to not double commands
  108. d = int(d)
  109. m = int(m)
  110. y = int(y)
  111.  
  112. #Put the input-ed date into a single variable
  113. birthday = date(y, m, d)
  114. #Work out the persons age
  115. age = now - birthday
  116. #Convert that to years (allowing for leap years too
  117. years = age.days / 365.25
  118. #Convert it to months also
  119. months = age.days / 12
  120.  
  121. ## Output the data!
  122. print "\nToday, your are:\n\n"
  123. print age.days, " days"
  124. print months, " months"
  125. print "or"
  126. print int(years), " years old!"
  127.  
  128. #Now just for fun we'll play with some list stuff
  129. #I'll try and make it look neat and 'readable' too.
  130. a = [\
  131. 'January',\
  132. 'February',\
  133. 'March',\
  134. 'April',\
  135. 'May',\
  136. 'June',\
  137. 'July',\
  138. 'August',\
  139. 'September',\
  140. 'October',\
  141. 'November',\
  142. 'December']
  143. #Prepare 'm' for 'a'
  144. m = m - 1
  145. #Add the 'st', 'nd', 'rd' or 'th' bit to the day!
  146. if d == 1 or d == 21 or d == 31:
  147. d = str(d) + 'st'
  148. elif d == 2 or d == 22 or d == 32:
  149. d = str(d) + 'nd'
  150. elif d == 3 or d == 23:
  151. d = str(d) + 'rd'
  152. elif d > 3 and d <= 20 or d >23 and d <= 30:
  153. d = str(d) + 'th'
  154. print "\n\nAlso I can tell you that you were born on: ", d, a[m], y
  155. #That's all folks!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
GreyInTheLaw is offline Offline
3 posts
since Mar 2008
Mar 2nd, 2008
0

Re: My first Python program, constructive critisism anyone?

Nice job! Here's a nitpicky critique -- take it as a compliment to your obvious talent at picking up a language in short order.

Am I correct in thinking that your background is in C?

(1) no '\' is needed after ','. Python accepts a comma as a line continuation character.

(2) the function to_upper() is correct, but also unnecessary. Python strings have a built-in method .upper() that does exactly the same (but faster, being in C).

(3) In general, modules should be imported at the top of the program.

(4) The error-checking can be done more concisely (and correctly -- you don't catch non-integer inputs) like this:

Python Syntax (Toggle Plain Text)
  1. while True:
  2. try:
  3. year = int(raw_input("What year were you born? "))
  4. except:
  5. print "enter an integer, please!"
  6. continue
  7. if year < 0:
  8. print "Impossible! You weren't born BC!"
  9. elif year > now.year: # << Note dynamic checking!
  10. print "Impossible! You aren't born in the future!"
  11. else:
  12. break

(5) the month-getting code should be shoved into a function for clarity. And, it can take advantage of Python's advanced structures:

Python Syntax (Toggle Plain Text)
  1. def get_month():
  2. months = ["JAN","FEB","MAR",etc.]
  3. while True:
  4. month = raw_input("What month were you born? ")
  5. month = month[:3].upper()
  6. if month in months:
  7. return months.index(month) + 1
  8. else:
  9. try:
  10. month = int(month)
  11. if 0 < month < 13:
  12. return month
  13. else:
  14. print "invalid month!"
  15. continue
  16. except:
  17. print "invalid month!"

This takes the place of the long if ... elif chain.

(6) Python really does include all the batteries. The datetime module can do all of this in one fell swoop:

Python Syntax (Toggle Plain Text)
  1. def extract_date(s):
  2. try:
  3. date = datetime.datetime.strptime(s, "%d %m %Y")
  4. except:
  5. try:
  6. date = datetime.datetime.strptime(s, "%d %b %Y")
  7. except:
  8. return None
  9. return date
  10.  
  11. while True:
  12. year = raw_input("What year were you born? ")
  13. month = raw_input("What month were you born? ")
  14. day = raw_input("What day were you born? ")
  15. bday = extract_date(day + " " + month[:3].title() + " "+ year)
  16. if bday == None:
  17. print "Illegal info!"
  18. continue
  19. else:
  20. break

Again, take all of these as incentive to keep learning; your original code is good.

Jeff
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Mar 2nd, 2008
0

Re: My first Python program, constructive critisism anyone?

Haha, you're right on the money there.
I did used to play around with C back when I was a windows user.
Now that I'm 100% Linux I sort of just...stopped. I guess that's why I'm here now, I miss playing around with coding.

I did see the built-in method upper, though I guess I didn't look close enough.

Also, I definitely like the

python Syntax (Toggle Plain Text)
  1. elif year > now.year: # << Note dynamic checking!

I feel daft for not doing that myself!

The rest is good thanks, it's exactly what I was after. My code worked but it was plain to see that it wasn't beautiful! Haha.

I'll add your comments to my source and carry on with a little more python today.




Thanks a lot!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
GreyInTheLaw is offline Offline
3 posts
since Mar 2008
Mar 3rd, 2008
0

Re: My first Python program, constructive critisism anyone?

Jeff, thanks for the idea. I was just working on a project that needed a secure date input. This what I came up with:
python Syntax (Toggle Plain Text)
  1. # a more secure way to enter a date
  2.  
  3. import datetime as dt
  4.  
  5. def enter_date():
  6. """
  7. asks to enter year, month and day and returns
  8. date info as <type 'datetime.datetime'>
  9. """
  10. def extract_date(s):
  11. try:
  12. # month given as a decimal number
  13. date = dt.datetime.strptime(s, "%d %m %Y")
  14. except:
  15. try:
  16. # month given as a 3 letter abreviation
  17. date = dt.datetime.strptime(s, "%d %b %Y")
  18. except:
  19. return None
  20. return date
  21.  
  22. while True:
  23. year = raw_input("Enter year (eg. 1979): ")
  24. # you can enter number of month, full name or 3 letter abbreviation
  25. month = raw_input("Enter month (eg. 9 or sep): ")
  26. day = raw_input("Enter the day of the month: ")
  27. date = extract_date(day + " " + month[:3].title() + " " + year)
  28. if date == None:
  29. print "Illegal info!"
  30. continue
  31. else:
  32. return date
  33.  
  34.  
  35. date = enter_date()
  36.  
  37. # testing ...
  38. #print date, type(date) # 2001-09-11 00:00:00 <type 'datetime.datetime'>
  39. #print date.strftime("%m/%d/%Y") # 09/11/2001
  40. #print date.strftime("%d%b%Y") # 11Sep2001
  41.  
  42. # do something with it ...
  43. today = dt.datetime.today()
  44. age = today - date
  45. # assumes week starts with Monday
  46. weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
  47. week_day = weekdays[dt.date.weekday(date)]
  48. print "Today is %s" % today.strftime("%d%b%Y")
  49. print "%s was %d days ago on a %s" % (date.strftime("%d%b%Y"), age.days, week_day)
  50.  
  51. """
  52. my output -->
  53. Enter year (eg. 1979): 2001
  54. Enter month (eg. 9 or sep): september
  55. Enter the day of the month: 11
  56. Today is 03Mar2008
  57. 11Sep2001 was 2365 days ago on a Tuesday
  58. """
Reputation Points: 309
Solved Threads: 43
Practically a Master Poster
ZZucker is offline Offline
676 posts
since Jan 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: wxPython Context Menu
Next Thread in Python Forum Timeline: python and dll craziness





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC