Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pizza maker: A Tutorial on Building Twitterbots


Published on

A simple introduction to building creative Twitter "bots" with Tracery and that explores the specific topic of pizza construction, naming and recommendation.

Published in: Engineering
  • Be the first to comment

Pizza maker: A Tutorial on Building Twitterbots

  1. 1. Create an account on Twitter, log in to Twitter with this account, then visit and Sign in.
  2. 2. Open your grammar with a { in the JSON window … The main rule of your Tracery grammar is called “origin.” The name of each rule is a non-terminal symbol that can be expanded using the right-hand-side. We refer to non-terminals by encasing them in # … # on the right-hand side of a rule.
  3. 3. Next, write rules to expand the non-terminals #meat# and #veggie# in our earlier rule for making a pizza Add as many options as you want to the right- hand-side of each rule; all are equally likely
  4. 4. Ditto for the non-terminals #cheese# and #sauce# Add as much variety as your imagination will allow … When Tracery expands a rule (to generate a pizza, say), it randomly picks from the right- hand-side options for each non-terminal.
  5. 5. We now write a rule for the last non-terminal, #base#, and close then our grammar with a final } Every non-terminal in every rule now has its own explicit rule definition, so our grammar is ready to start generating.
  6. 6. This handy button on the bottom right allows you to test the grammar, and tweet the results you like … Use this drop-down menu to select the frequency with which your bot will tweet the outputs of its Tracery grammar.
  7. 7. Finally, save your bot on BotPizzaKitchen Choose to make your grammar visible to users of the site.
  8. 8. Now, what if we want our grammar to give a name to each pizza? I can think of a few …
  9. 9. We can make a name by joining two namelets But our names bear no specific relation to their pizzas
  10. 10. If only the expansions of #Meat#, #Cheese# and the other ingredients were influenced by the expansions for #Prefix# and #Suffix# But Tracery grammars are Context-Free: every non- terminal like #Meat# is expanded in a null context, independently of all others. No Context, No Influence!
  11. 11. Here’s what we aim for: the Cave wall prefix suits Quorn, while Cowboy is apt for Ranch sauce. The name influences the ingredients. Here’s a naïve solution: write specific pizza rules that hardcode relations across non-terminals. So #Prefix_A# generates names that go with #Meat_A#, and so on.
  12. 12. *&$^$% Flippin’ Nora!
  13. 13. Pre-Name Ingredients Prefix Suffix Post-Name Ingredients So split the generator into two self-contained components
  14. 14. Meat Prefix Suffix Vegetable on Cheese & Sauce on Base Meat & Vegetable Prefix Suffix on Cheese & Sauce on Base Meat & Vegetable on Cheese Prefix Suffix on Sauce on Base Meat & Vegetable on Cheese & Sauce Prefix Suffix on Base We’ll need four high-level rules for four different kinds of split.
  15. 15. Suffix Vegetable on Cheese & Sauce on Base Suffix Vegetable on Cheese & Sauce on Base Suffix Vegetable on Cheese & Sauce on Base Suffix Vegetable on Cheese & Sauce on Base Each self-contained component has internal agreement that can vary in the number of dependency pairings Meat Prefix 1 Possibility 4 Agreement Possibilities Yeah!
  16. 16. Our new top-level rules are below, and produce named pizzas as above. In total, the new grammar has 100 rules.
  17. 17. You can download the grammar and this spreadsheet from our Github repository All the data for our grammar is stored in a spreadsheet
  18. 18. What a great flippin’ pantry!
  19. 19. CheapBotsDoneQuick allows us to make our bots responsive to tweets that explicitly @ mention them. So let’s make our bot deliver pizza recommendations that match specific tastes. I could murder a seafood pizza!
  20. 20. First, we need to add a new column to our DB …
  21. 21. The type of a pizza is a function of the type of its ingredients. So for each qualification on ingredients, generate new rules for pizzas and their elements.
  22. 22. Maker Specialized Namer Pizza-specific Combined Grammar
  23. 23. The named-pizza maker has 100 rules. This jumps to 800 rules when we add qualifications, and to 1500 rules when we add negative qualifications as well.
  24. 24. Your pizza, M’lord. But our Tracery grammar still fits into so let’s press on with the delivery of speciality pizzas. Choose the Reply option for your bot (still in Beta) so you can configure how it will reply to @ mentions from others.
  25. 25. { “.”: “#pizza#” } Response grammars use a simpler JSON format, with just one element on the right-hand-side. But you CAN refer to non-terminals in the main grammar here. The left-hand-side of a response rule is not a non-terminal, but a string that must literally match part of an @mention
  26. 26. Each qualification of an ingredient is listed on the left. The corresponding pizza non-terminal is on the right. These response rules are applied in the given order, so it is important that the negative qualifications (e.g. “no meat”) are listed before the positives (e.g. “meat”).
  27. 27. Each left-hand-side can also be a regular expression. Use “.” to match any string. Use [x|X] for a choice between “x” and “X”, as in the case-insensitive texts above.
  28. 28. Your F**king Wine, Sir. Let’s consider how our pizza bot might usefully interact with others. How about another bot that suggests wine pairings for our newly invented pizzas?
  29. 29. We need to whip up a cocktail of complementary grammars. One will map from foods to wines, and another will listen for the triggers to exploit this mapping.
  30. 30. To start, we should codify our wine-pairing knowledge in an explicit form, as in this very spreadsheet …
  31. 31. Each food-feature-rule (non-terminals of the form “feature bev”) maps onto its own specialist list of recommendations Add a separate rule for each feature of the food on which a wine pairing can be predicated …
  32. 32. Now, we need a means of invoking each food- feature-rule, so for each food feature, add a stimulus:response pair to the response grammar.
  33. 33. Now we need to get the bicameral parts of the grammar to talk to each other. We must make sure that every pizza created by our bot mentions the name of a recommendation bot, such as itself
  34. 34. Now our recommender can be triggered by any mention of specific ingredients (or a whole class of ingredients) in our pizza descriptions … … and respond accordingly, as below.
  35. 35. But our wine grammar offers pairings on the basis of just a single ingredient! Fancy a drink with your pizza? Flippin’ heck, you’re right!
  36. 36. Solution: consider all pairwise combos of ingredients that suggest the same wine! For each combo, add an explicit recomm- endation rule to the response grammar.
  37. 37. Notice the use of the wildcard characters .+ here. The dot . matches any character while the + means one or more uses
  38. 38. Now our response grammar can recommend wine for a pairing of ingredients.