My first Python program, constructive critisism anyone?

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Mar 2008
Posts: 3
Reputation: GreyInTheLaw is an unknown quantity at this point 
Solved Threads: 0
GreyInTheLaw GreyInTheLaw is offline Offline
Newbie Poster

My first Python program, constructive critisism anyone?

 
0
  #1
Mar 1st, 2008
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.

  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!
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: My first Python program, constructive critisism anyone?

 
0
  #2
Mar 2nd, 2008
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:

  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:

  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:

  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
Reply With Quote Quick reply to this message  
Join Date: Mar 2008
Posts: 3
Reputation: GreyInTheLaw is an unknown quantity at this point 
Solved Threads: 0
GreyInTheLaw GreyInTheLaw is offline Offline
Newbie Poster

Re: My first Python program, constructive critisism anyone?

 
0
  #3
Mar 2nd, 2008
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

  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!
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 666
Reputation: ZZucker is on a distinguished road 
Solved Threads: 38
ZZucker's Avatar
ZZucker ZZucker is offline Offline
Practically a Master Poster

Re: My first Python program, constructive critisism anyone?

 
0
  #4
Mar 3rd, 2008
Jeff, thanks for the idea. I was just working on a project that needed a secure date input. This what I came up with:
  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. """
Never argue with idiots, they'll just bring you down to their level and beat you with their experience.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC