This example works as a birthday reminder. <br>It demonstrates the use of dictionaries and several other things (like functions) already covered in the existing examples, but now put in a larger program.<br><br>PS. I now notice I've pushed this code with "switch" in comments instead of "if-else", I'll change that.<br>
<br>Dinko Galetic<br><br>diff --git a/data/GSOC examples/birthday reminder b/data/GSOC examples/birthday <br>new file mode 100644<br>index 0000000..eca9458<br>--- /dev/null<br>+++ b/data/GSOC examples/birthday reminder <br>
@@ -0,0 +1,201 @@<br>+# The purpose of this example is to demonstrate what is a dictionary in Python.<br>+# This will also cover:<br>+ # functions,<br>+ # switch, and<br>+ # writing to text files.<br>+<br>+<br>+# This function adds a birthday to the list of birthdays.<br>
+# Simple, isn't it? <br>+# There's one flaw, though: In case we've already stored the data for that<br>+# person, it will overwrite that data.<br>+def add_birthday(person, day, birthdays):<br>+ birthdays[person] = day<br>
+<br>+# This does the same as the previous function, but checks if we already have<br>+# the birthday of that person remembered and warns us in that case.<br>+# Practice: This function is not used in this example, only defined. <br>
+# Could you change the code so that it is used instead of <br>+# the default "add_birthday" function?<br>+def add_birthday_safer(person, day, birthdays):<br>+ if birthdays.has_key(person):<br>+ print "You've already entered " + person + "'s birthday as:", <br>
+ print birthdays[person]<br>+ print "Would you like to overwrite that with " + day + " (y/n)?"<br>+ response = raw_input("Response: ")<br>+ # Practice: Add some more possible answers (like with capital letters)<br>
+ if response == "n" or response == "no":<br>+ # "return" marks the end of the function<br>+ return<br>+ else:<br>+ birthdays[person] = day <br>
+<br>+# To change an existing record: just overwrite whatever was there before! <br>+# It will simply add a new record if there wasn't a person with the given name,<br>+# and that is fine. Because of that, we don't have to check if the record exist<br>
+def change_birthday(person, day, birthdays):<br>+ birthdays[person] = day<br>+<br>+# This function deletes a birthday.<br>+def forget_birthday(person, birthdays):<br>+ if birthdays.has_key(person):<br>+ del birthdays[person]<br>
+ else:<br>+ print "No such person."<br>+<br>+# This function check if it's anyone's birthday today.<br>+def check_birthdays(birthdays):<br>+ # this will get us the today's date in the form ddmm, the same<br>
+ # as we enter it. We don't need the year, most people have birthdays<br>+ # each year. :) <br>+ # Practice: Who doesn't?<br>+ today = time.strftime("%d%m")<br>+<br>+ none_today = True<br>
+<br>+ for person in birthdays:<br>+ bday = birthdays[person]<br>+ # How do we know which birthday is it? <br>+ # Easy: current year - birth year.<br>+ # time.strftime("%Y") gets us the current year, and the birth year<br>
+ # is written in "bday" variable, from 4th index to the last.<br>+ # Since both are written as strings, we have to turn them to numbers<br>+ # before we can subtract them, and we do that by passing them to the in<br>
+ # function. When they are subtracted, turn the result back into a strin<br>+ # by passing it to the str() function. <br>+ which = str( int(time.strftime("%Y")) - int(bday[4:]) ) <br>+<br>
+ if bday[0:4] == today:<br>
+ print "It's " + person + "'s " + which + ". birthday, yay!"<br>+ none_today = False<br>+<br>+ if none_today:<br>+ print "No birthdays today."<br>
+<br>+# Practice: Could we make the output of this function nicer? <br>+# For example, change it to the form of dd.mm.yyyy instead of ddmmyyy ?<br>+def print_birthdays(birthdays):<br>+ for person, day in birthdays.items():<br>
+ print person + " was born on " + day + "."<br>+ if len(birthdays.items()) == 0:<br>+ print "There are no birthdays memorised."<br>+<br>+# This function takes a name and finds that person's birthday.<br>
+def find_birthday(name, birthdays):<br>+ if birthdays.has_key(name):<br>+ print name + "'s birthday is on: " + birthdays[name]<br>+ else:<br>+ print "You never entered " + name + "'s birthday!"<br>
+<br>+<br>+def save_to_file(filename, bdays):<br>+ # Warning: If there already exists a file with this name, opening it in "w"<br>+ # mode will delete the existing file and create a blank one!<br>+ # Opening in "a"ppend mode adds everything to the end of an existing file, <br>
+ # but we won't use it here.<br>+ # Practice: Try writing a program which appends to text files to see how it<br>+ f = open(filename, "w")<br>+ # Practice: What does str(bdays) give us? Try it on a dictionary variable!<br>
+ text = str(bdays)<br>+ f.write(text)<br>+ f.close()<br>+ <br>+def load_from_file(filename):<br>+ my_file = open(filename, "r")<br>+ text_from_file = my_file.read()<br>+<br>+ # eval() takes text and then runs it as if it were Python code.<br>
+ # For us, it will turn a textual representation of a dictionary to a functi<br>+ # Python dictionary.<br>+ bday_dictionary = eval(text_from_file)<br>+<br>+ # Return that to whoever called load_from_file() in the first place.<br>
+ return bday_dictionary<br>+<br>+# This function displays the menu which you see when you run the program.<br>+def menu():<br>+ # Here we will store all the birthday data. Notice the {} - that's how we<br>+ # define that a variable is a dictionary. <br>
+ # This will get us an empty dictionary, and we'll see how to fill it<br>+ # with data in a moment.<br>+ birthdays = {}<br>+ <br>+ # We'll display the menu in an infinite loop.<br>+ # The condition in while() will always be true, since it's, well.. True.<br>
+ # The entire function, though, will end when the user enters "7".<br>+ while (True): <br>+ # Print thirty # and move to a new line.<br>+ print "#" * 60 + "\n"<br>+ print "Please choose from the following: "<br>
+ print "\t1. Print all birthdays we have remembered."<br>+ print "\t2. Check if someone's birthday is today."<br>+ print "\t3. Find someone's birthday."<br>+ print "\t4. Add a new birthday."<br>
+ print "\t5. Change the data for an existing birthday."<br>+ print "\t6. Delete an existing birthday."<br>+ print "\t7. Write all birthdays to a file."<br>+ print "\t8. Load birthdays from a file."<br>
+ print "\t9. Exit."<br>+ choice = raw_input("Your choice: ")<br>+ if choice == "1":<br>+ print_birthdays(birthdays) <br>+<br>+ elif choice == "2":<br>
+ check_birthdays(birthdays)<br>+<br>+ elif choice == "3":<br>+ print "Enter your friend's name: "<br>+ name = raw_input() <br>+ find_birthday(name, birthdays)<br>
+<br>+ elif choice == "4":<br>+ print "Enter your friend's name: "<br>+ name = raw_input()<br>+ print "Enter " + name + "'s birthday (ddmmyyyy): "<br>
+ birthday = raw_input()<br>+ add_birthday(name, birthday, birthdays)<br>+<br>+ elif choice == "5":<br>+ print "Enter your friend's name: "<br>+ name = raw_input()<br>
+ print "Enter " + name + "'s birthday (ddmmyyyy): "<br>+ birthday = raw_input()<br>+ change_birthday(name, birthday, birthdays)<br>+<br>+ elif choice == "6":<br>
+ print "Enter your friend's name: "<br>+ name = raw_input()<br>+ forget_birthday(name, birthdays)<br>+<br>+ elif choice == "7": <br>+ print "Enter the name of the file in which to store: "<br>
+ filename = raw_input()<br>+ print "Location of that file (can be blank): "<br>+ filename = raw_input() + filename<br>+ save_to_file(filename, birthdays)<br>+ <br>
+ elif choice == "8":<br>+ print "Name of the file with stored birthdays: "<br>+ filename = raw_input()<br>+ print "Location of that file (can be blank): "<br>
+ filename = raw_input() + filename<br>+ # Warning! Doing this will overwrite anything we're put in our dict<br>+ # so far with that is saved in that file.<br>+ birthdays = load_from_file(filename)<br>
+<br>+ # Practice: Currently, there's no way for a user to load data from two<br>+ # different files at once. It would be possible to ask for two filename<br>+ # a write a function which would take those two filenames, read from bo<br>
+ # files and combine their content into one dictionary.<br>+ # A hint: dictionaries have a method called "update", <br>+ # look it up to see what it does!<br>+<br>+ elif choice == "9":<br>
+ return<br>+<br>+# This is where our program starts executing. It enters the menu() function and<br>+# runs it until you choose to leave.<br>+print "Welcome to the birthday reminder."<br>+import time<br>
+menu()<br>+print "Exiting the birthday reminder... Bye!"<br><br>