Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drawing Names (A Christmas Name Drawing Application)

0.00/5 (No votes)
23 May 2012 1  
A Christmas name drawing application using DHTML, JavaScript, XML, C#, Forms, VS2008, .NET 3.5, encryption.

The code

Once you download the .Zip file you must unzip it. For example if you unzipped to the directory c:\NameDrawing then you would get a folder and file tree that looks like the following:

The root folder only contains one file NameDrawing.sln which is the VS2010 solution file. In that folder, there is a subfolder c:\NameDrawing\NameDrawing that contains all the project files and project subfolders. One that is of most interest is the folder c:\NameDrawing\NameDrawing\DataFiles_2011. If you decide to use this project then all the .html files in that folder plus the single .jpg file and the file named Crypt.js will become the end result of the project. In particular the file named index.html is the file that the participants in the name drawing event will bring up in their web browsers.

Short version

  • The project consists of source code for a VS2010 C# Forms Application that writes a client side JavaScript file that contains a function that is executed from the file index.html. The application uses an XML data file for its input. The sample files: index.html, drawing_names.xml, and Wish-Lists.html are included.
  • To use this project in the 'real-world', you would need to:
    1. compile the C# VS2010 project (producing the executable)
    2. edit the drawing_names.XML data file (introduce real user names and pass phrases)
    3. edit the index.html file (introduce real user names)
    4. edit the 'extra' wishlists.html (introduce real user names)
    5. run the application (producing the JavaScript)
    6. publish all the files to some website somewhere

To see a 'working-version' of the result for the 2008 Christmas season, visit: http://papa.poemy.net/2008_Drawing_Names/index.html.

Now that I write all that down it seems like a lot, but given this application is to be used at Christmas time, you have a few months to get it together if you want to use it for your group of family or friends for the 2012 Christmas season.

Note: I am not an accomplished GUI designer or super-duper OO designer. My real-world talents lie in middleware, communications, and OS internals design and implementation.

The kind of stuff in this project, for me, is pure hobby/fun stuff. This means that 100% of the technology in this project is pure 'hacking', I do not do any of this sort of stuff for a living. So ... this means, whatever you think about this project --- you are probably correct (good, bad, ugly, other).

Also, I think comments/changes/etc... would be grand and are appreciated and accepted. I think there is also the ability to collaborate when you work on CodeProject stuff so the absolute best result would be that the app would be interesting enough to stimulate that sort of behavior. I know I've got a lot of ideas about messing with it. I will post changes and extensions here and perhaps in a new article if they get big enough.

Introduction (Motivation)

As a child in a large family we always picked a single name out of a hat rather than purchase a present for each sibling. Then as adults we continued this tradition and further included our spouses in the event. As time went by, the name drawing event became a Thanksgiving and, on some occasions, a Summer Beach Trip event. There were lots of discussions about not choosing your own name or your spouse’s name and lots of put-backs and redraws, etc. Of course I could not resist the temptation, and decided to write an application that would simulate a random hat draw, keep a history of past draws, and enforce rules of not drawing your own name or your spouse’s name. And as time went on, even 'cheats' could be added when someone just had to draw someone else's name that year. Additionally, the concept of a "Secret Santa" came up where one person gets a second name and gives that person an anonymous present.

Background

The original CodeProject version was done in 2009.  Since that time there have been enhancement requests and a bug report so this version in 2011 represents the modifications to implement the changes and fix the bug. 

Complexity level

For me something is complex if I've never done it before. If I can get an example that is written in syntax that I understand then I can usually 'noodle-it-out'. I'll look at it, knowing all the pieces of the syntax and knowing what it does and usually say, "Oh yes, I get it." Or perhaps "Ah ha!" so that's how it is done. If you read through this and get to any point where you think, "What is he doing here?" then make a comment to this article and I'll try to write a bit about that either as a response to the comment or even add a section to the entire article. You do not have to be specific, you can ask global questions, and certainly specific questions too.

Using the application

Here is what the application does: It writes a JavaScript named "Crypt.js" that can be referenced by a web page. A sample of the web page "index.html" and its background .jpg file as well as some sample "Wish List Pages" are included as part of the project. To use this project you would edit the sample index.html page and sample "Wish List Pages" as needed.

To use the application which actually does the name drawing event, you need to edit the sample .XML file and insert content that matches up with the participants that will be engaged in the name drawing activity. You can (if it is available) even add history and even add some 'cheats' to the name drawing event.

Once the .XML file is updated, you execute the application by pressing the buttons in the GUI. To test the results, you load up the index.html and enter pass phrases and press name buttons.

About the data

The input data to the application is arranged in a .XML file. I actually authored the file before creating the .XSD file. VS2010 has a nice feature where it will extract a likely looking .XSD file to go with an XML file. After doing that I would modify the XML and remember to modify the XSD accordingly. Here is a graphic that illustrates the structure of the XML (the graphic was created by VS2010).

Drawing_Names/schema.png

How it all works 

The finished object is a web page "index.html" that you publish somewhere on the web along with the supporting script file "Crypt.JS" and the other supporting .html files (wish lists) and a background .jpg file. You then invite the folks who are participating in the name drawing event to visit the site.

Each person enters his "pass phrase" and then presses his "button". This action sends the pass phrase to the JavaScript which decrypts two messages for that user. The first message tells the user whose name he drew and the second message tells the user whether or not he is 'The Secret Santa' and if so who he should get an extra present for.

Additional buttons on the page bring up the "Wish Lists" for the participants. Of course, before you start all this, you get the participant names and pass phrases and other information and enter it into the .XML file and edit the .HTML file accordingly so that each participant's button has his name on it. Additionally as the event goes forward, you can update the "Wish Lists" .html files associated with each participant as they send you, the administrator, the content of their wish lists (phew... now that's a topic for an application feature, i.e., make the users do all that on their own).

About the structure of the application

The application was created using the Visual Studio 2008 C# Windows Forms Wizard. What this wizard does is bring up a blank window onto which you place controls. This application is designed around the buttons (controls) you can press. What follows is a high level discussion of the application given in terms of the controls you can manipulate. A more technical discussion of the application follows this high level discussion.

  • Load XML File - This action opens a "Folder Browser Dialog" that allows the operator to locate the folder that contains the data files. Once the folder is located and the browser dialog is dismissed, the .XML file is opened and parsed filling in the data values in the application. If the check box named "Show results" is checked, the application echoes the values of the data in a list box. Here is a screenshot of the application just after clicking on the Load XML File button:
  • Draw Names - This action is enabled after the "Load XML File" is executed. This action will do the "drawing names" action described above. Because this action simulates a "random-drawing" it may be the case you can get to the "bottom-of-the-hat" and you find your own name or another name that you can not use like your spouse's or some name you drew in years past. So in this case you need to start over. The logic is designed to retry up to 100 times then quit with a failure. You can put in enough history in the XML file so that no solution is possible. In this case you need to remove some of the history or adjust the cheats/spouse relationship(s).
  • Note: You can analyze the .xml file to determine if a solution for this year is possible. Such an analysis would be like doing a 'draw from hat' event without doing any random stuff. One way to do this is to walk through the data (including history and rules) and choose the first set of name pairings that works. In this, combinatorial, approach you could also get to the 'bottom-of-the-hat' and find that no solution was possible and in that case the function would just return the value "ADJUST RULES/HISTORY NO SOLUTION POSSIBLE" straight away.

  • Write Script - This action is enabled after the "Draw Names" action is executed. This action will go through the data and encrypt the messages associated with each participant using that participant's "Pass Phrase". The encryption technique is the only perfect encryption technique that exists, which is to XOR the Pass Phrase with the Clear Text. An XOR operation is such that if applied twice undoes itself. And if the Pass Phrase is a random string it will reduce the Clear Text to a random string. In cryptographic terms this is called a "One Time Pad". After all the messages have been encrypted the Write Script action will create the java script named "Crypt.JS". This script consist of three parts: The top, middle, and bottom. The top is just the opening statements of the java procedure. The middle is an array of the encrypted text created using XOR encryption. The bottom is the logic of the Java function. The java function XORs the pass phrase with the encrypted messages and puts the resulting clear text in the text boxes of the .htm file. The pass phrases are not in the java script or in the index.html file so if someone forgets his pass phrase he must appeal to the administrator to dig it out of the .XML file and send it to him.
  • View Page - This action is enabled after the "Write Script" action is executed and opens the index.html file in a browser control. You can test the operation of the web page after pressing this button. Here is a screen shot of the index.html file loaded in a web browser control:
  • Drawing_Names/Screen_003.png

In addition to the main buttons that control the application, there is one more button labeled "Crypt" and three text boxes associated with the button. You enter the clear text and pass phrase in the correct box and pres the Crypt button and see the resulting crypt text appear in the third text box. This behavior is independent of the operation of the rest of the application but does call the same function that the main application calls. If you paste the encrypted text into the clear text box and use the same pass phrase as you did to encrypt and press the Crypt button the clear text is 'decrypted'. Here is a screen shot of such a test where clear text is encrypted:

Drawing_Names/Screen_004.png

Here is the class diagram of the whole application. The class named "publicDATA" is just used to organize all the public data into one place. All those members could have been declared public in the main application without encapsulating them in their own class.

Drawing_Names/ClassDiagram_Graphic.png

Some Technical Details

  • loadXMLFile_Click - This is function that loads the XML file (and is set up to validate it) and then parses it filling in parts of an instance of the publicData class.
  • The way the function works is that it falls through a series of while(Reader.read()) loops. Inside the large outer loop are a set of if/then/else statements that decode the major elements of the XML file which are thisYearsSecretSantaMessage, thisYearsCheatSheet, historyLog, and nameList. If the display results check box is active this function also calls displayXMLContent. Additionally since this is the first function called it initializes the random number generator.

  • drawNames_Click - Fills in this year's names and chooses a secret Santa and the secret Santa target. In order to simulate picking names at random out of a hat the values are generated from a random set of numbers. The two functions doTheNameDraw and doPickSecretSanta actually choose the values. Since these function could fail given enough history was in the XML file to keep a valid pick from occurring or the more unlikely event that a long string of random numbers would cause a failure; the drawNames_Click does cater for such a failure. It will also display the results when that check box is in the checked state.
  • Note: The doPickSecretSanta is done before the doTheNameDraw because one of the built in rules is that you can not draw the name of the same person who was picked to be the secret Santa target, assuming you are this year's secret Santa. Here are all the rules:

    • [RULE-1] If you have been the secret Santa in the past you may not be it again.
    • [RULE-2] If you have been the secret Santa target in the past you may not be it again.
    • [RULE-3] You can not draw your own name (except via a cheat which would amount to you opting out of this year's event).
    • [RULE-4] You can not draw your spouse's name (given you have a spouse in the list, no multiple spouses).
    • [RULE-5] You can not draw the person's name that you did in years past (except via a cheat).
    • [RULE-6] If you are the secret Santa this year you may not draw the same name as the secret Santa target.
  • writeScript_Click - For each message that needs to be encrypted this function calls the Crypt function. After this the function writes the Crypt.JS file.
  • bViewPage_Click - Finally once the script has been written you can display the index.html file and exercise it.

About Crypt.JS and index.html

Crypt.js is a file that contains a single java script function that 'knows' about the structure of its companion index.html.

index.html is an html file that consists of a bunch of buttons (one for each participant) and three text boxes; one for the pass phrase one for the "Here is the person's name you drew." and one for the "You are (or not) the Secret Santa this year." There is another set of buttons that 'go-to' the "Wish-List.html" pages.

The index.html web page can be totally modified. And, of course, in the process of actually putting together a 'real-world' version of all this you would indeed modify the index.html file and the wish-lists.html files. To go along with those edits you would collect from each participant (or assign to each) a "Pass Phrase".

Once you have everyone's name, pass-phrase, spouse-relationship (or not) you modify the drawing_names.xml data file. You may custom tailor each message that is presented when a participant's name is drawn and you may custom tailor the message that is presented for each person who is NOT the Secret Santa for the year and you may customize the single Secret Santa message. Note that the special characters '$' and '*' in that string are replaced by the name of the secret Santa and his/her target, if you forget them then the secret Santa message will not work correctly.

So given you have edited the index.html file the drawing_names.xml file and compiled the application then you run the application, surf to the location of the .xml data file and read the data file draw names and write the script. The application has a built-in window for viewing the final index.html file.

Points of Interest

The major motivation for converting the application to a C# app was to convert all the data to a file could be read in, instead of having to actually edit the source code. And I thought the logical choice for the format of the data file was XML. So I needed to know how to read an XML file and have the contents populate the data for the application. It turns out that I learned two things that were quite interesting.

The first was: The way you extract information from an XML file using XMLReader is very simple (the nested loops and select statements).

The second thing was: Apparently .NET 3.5 does not have a clue how to validate XML files from a schema when element attributes are involved.

Note: About .NET 3.5:

  1. It is busted or
  2. I'm no setting up the schema and/or schema validation logic correctly.

History

  • (New) --- 04 Dec 2011 - Uses VS2010 to build. (Uploaded a new .zip file and changes some of the text and graphics to reflect this. Added some features that have been requested and fixed a bug was reported against the application. I also changed the content of the .ZIP file to NOT include the executable file. (You now have to build it from the source files.)
    • Now Uses --- Visual Studio 2010.
    • Added To The Schema --- A 'Cheat' now has a cheat type that can be one of the following:
      • MustPick - This is the original 'Cheat' type where some participant has a predetermined pick.
      • MustNotPick - This is a new 'Cheat' one where some participant may never pick some other participant.
      • TheSecretSantaTarget -  This 'Cheat' sets the Secret Santa Target to be the current year's pick of some participant.
      • MayNotBeSecretSanta - This 'Cheat' prevents some participant from being the Secret Santa.

      Please note:  If you currently use the application and want to have some of the new content then you will need to upgrade your current .XSD and .XML file. 

    • Fixed a bug -- that related to the history array.  Each year of history has a participant list in it that contains that participant's activity. That array (participant) was being referenced by an index that is 'one-based' and the array itself is 'zero-based' so the bug fix was to subtract one from the index thus creating the correct index for the 'zero-based' array. 
  • 08 Feb 2009 - No change in the .zip file I just added the "Complexity" paragraph.
  • 07 Feb 2009 - No change in the .zip file I just edited the text of this page.
  • 23 Jan 2009 - Initial Post (Well actually I did forget to set the 'under construction' check box and even got a few comments pointing out that the article looked a bit unfinished). Given that you, the reader, have seen a few projects on Code Project and are familiar with how they are usually organized please feel free to leave comments on how it could be improved.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here