Message Boards Message Boards

5
|
19977 Views
|
9 Replies
|
15 Total Likes
View groups...
Share
Share this post:

How to quickly code a Secret Santa Generator

Yesterday, @Jonathan Wallace asked me how I would make a Secret Santa drawing program in the Wolfram Language, and to my surprise it turned out to be a really simple CloudDeploy of a FormFunction. Here is how I made it:

1. To create a FormFunction with a group of double fields to enter names and emails that can be added and deleted I used RepeatingElement with CompoundElement:

    FormFunction["participants"->RepeatingElement[CompoundElement[<|"Name"->"String","Email"->"EmailAddress"|>]]]

FormFunction

2. The random pairing algorithm is really simple:

    Thread[Rule[list = RandomSample[Range[10], 10], RotateLeft[list, 1]]]

{3->8,8->9,9->6,6->2,2->4,4->10,10->1,1->7,7->5,5->3}

3. Then I created a title for the FormFunction using the Santa popular curve:

    title=Rasterize@Labeled[Entity["PopularCurve","SantaCurve"]["Image"]/.{Line->Polygon,RGBColor[0.24720000000000014`,0.24`,0.6`]->Opacity@.5,True->False},
    Style["Secret Santa Generator","Title"],Top]

Title Secret Santa

4. Then to deliver the drawings to the participants I Map the following SendMail function to the values obtained from the submitted form:

    SendMail["To" -> #[[1, 2]], "Subject" -> #[[1, 1]] <> " BUYS FOR " <> #[[2, 1]], 
     "Body" -> #[[1, 1]] <> " BUYS FOR " <> #[[2, 1]] <> "\n\nSecret Santa Generator powered by the Wolfram Language."]

5. The final FormFunction that combines steps 1 to 4 should look like this:

    form=FormFunction[
    "participants"->RepeatingElement[CompoundElement[<|"Name"->"String","Email"->"EmailAddress"|>]],
    (Map[SendMail["To"->#[[1,2]],"Subject"->#[[1,1]]<>" BUYS FOR "<>#[[2,1]],
    "Body"->#[[1,1]]<>" BUYS FOR "<>#[[2,1]]<>"\n\nSecret Santa Generator \nhttps://wolfr.am/99kaasSX \n\n\t\t\t\t powered by the Wolfram Language."]&,
    Thread[Rule[list=RandomSample[#participants,Length[#participants]],RotateLeft[list,1]]]];
    "Thank you! The Secret Santa drawings have been delivered to all the participants!")&,
    AppearanceRules-><|"Title"->title,
    "Description"->"Enter the names and email addresses for the gift exchange. The Wolfram Secret Santa Generator will handle the rest!"|>,
    FormTheme->"Red"]

6. Which can be shared with all the gift exchange organizers by uploading it to the Wolfram Cloud:

    CloudDeploy[form, "SecretSantaGenerator", Permissions -> "Public"]

Secret Santa Generator

Once the organizers have submitted the list of participants, the participants will receive immediately an email with their match:

enter image description here

Happy Secret Santa Week!

Attachments:
POSTED BY: Bernat Espigulé
9 Replies

I found the issue. I have the setting "Format type of new output cells" set to "TraditionalForm". When I change it to StandardForm everything works. I've submitted a ticket to support because I don't think TraditionalForm should affect form generation like that, though there might be a reason for it. I don't remember this being an issue in 10.0 when I first started playing with FormFunction; I've had the output form set to TraditionalForm for as long as I can remember.

POSTED BY: Eric Smith

Hi Eric, it looks like your Mathematica $Version is 10.0 or 10.1. You shouldn't see this wrong formatting in newer versions.

POSTED BY: Bernat Espigulé

Thank you Dorothy for your interest in this Secret Santa Generator. Unfortunately, there isn't a particular gift exchange event planned. This is just a tool for everyone that wants to organize one.

POSTED BY: Bernat Espigulé

Forgive me if this is hijacking the thread, but I tried out Bernat's FormFunction and my FrontEnd is returning

FormFunction[FormObject[<|participants-><|Interpreter->RepeatingElement[<|Interpreter->CompoundElement[<|Name-><|Interpreter->String|>,Email-><|Interpreter->EmailAddress|>|>]|>]|>|>]]

instead of the actual form. It's happening in the documentation too, so it's not a syntax error. Is there an option I'm missing?

POSTED BY: Eric Smith

Before one signs up for this, especially since today is Dec. 23, one might like to know:

1) how long this "week" will last

2) what sort of "gifts" one should expect to exchange

3) will there be a big "reveal" gathering?

Are the exchanged gifts to be snippets of code that might be run to generate greetings or fun graphic displays. If this is the avenue taken, then how would one send an anonymous email that would not be considered spam? Could the secret santa generator be augmented to allow the original email person to send an email each day to their specific recipient that would be have the from field be filled out with "secret santa" instead of the actual person's email until the reveal day?

Just some things to consider.

Are we actually doing this? I wanted to know details before signing up.

Thanks, Dorothy

POSTED BY: Dorothy Evans

I'm not sure though what is harder to understand: the Thread command or the @@@ and Partition[..,2,1,1]? I think I'd favour Bernat's solutions in terms of comprehensibility, though still complex! Here are some minimized versions, though this might reduce the legibility...

MapThread[Rule,{#,RotateLeft@#}]&@RandomSample@Range@10
Thread[Rule[#,RotateLeft@#]]&@RandomSample@Range@10
Thread[#~Rule~RotateLeft@#]&@RandomSample@Range@10
Rule@@@Partition[RandomSample@Range@10,2,1,1]
POSTED BY: Sander Huisman

Just another idea crossed my mind, a bit shorter:

Rule@@@Partition[RandomSample[Range[10]], 2, 1, 1]

We are basically making a CycleGraph with random vertices labeling:

Graph[pairs, GraphStyle -> "SmallNetwork"]

enter image description here

POSTED BY: Vitaliy Kaurov

Good point Sander! That makes the code shorter and more readable.

POSTED BY: Bernat Espigulé

Really cool and nifty use of the technology-stack!

Thread[Rule[list = RandomSample[Range[10], 10], RotateLeft[list, 1]]]

Nice trick to make sure no one gives something to itself!

It can be slightly simplified: RandomSample[Range[10]], second argument is not required. Same for RotateLeft, the 1 is the default and the argument can be omitted:

Thread[Rule[list = RandomSample[Range[10]], RotateLeft[list]]]
POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract