Group Abstract Group Abstract

Message Boards Message Boards

5
|
23.6K 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

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

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é

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
POSTED BY: Dorothy Evans

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é
POSTED BY: Sander Huisman

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

POSTED BY: Bernat Espigulé

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

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
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard