Food Variety

Try It Out

Open this example in Repiano

Introduction

Some people happily will eat the same thing every day. Most of us get tired of things and crave variety. The problem is we often forget what we haven't had recently - "oh yeah, I like that and it's been a while since I made it."

This example demonstrates using a choice system to suggest what to eat based on your preferences while encouraging variety over time.

Configuration and Reasoning

When deciding what to eat, there are three factors to consider: how much you like each food, whether you've had that specific food recently, and whether you've had that type of cuisine recently. Each of these becomes a reason in the choice configuration.

The Preference reason is straightforward - it's a property reason that pulls the preference value directly from the collection. If your tastes change or you realize a preference rating isn't quite right, just update it in the collection.

The Recent Food reason uses recency to highlight foods you haven't eaten in a while. The longer it's been since you had something, the more appealing it becomes. This is set to use a scaling of 0.5 (square root), which means the boost diminishes as time passes - having something 16 days ago gets roughly half the boost of something from 4 days ago. This scaling is somewhat arbitrary but feels about right for how food preferences work.

The Recent Cuisine reason works similarly, but tracks the cuisine type instead of the specific food. This helps ensure you don't get stuck in a rut with one type of food - if you've been eating a lot of American food lately, this nudges you toward trying Mexican, Thai, Korean, or other cuisines.

All three reasons have equal weights of 1, which is also arbitrary. The intent is that you'd adjust these based on your priorities. If you've been eating American food way too much lately, you could boost the cuisine weight significantly and see what other options rise to the top.

The collection for this example was generated with Claude's help to create a realistic set of foods with variety across cuisines and preferences.

Why recency instead of benefit?

There's an important design choice in this example: why use recency reasons instead of benefit reasons? There are two ways to encourage variety:

  1. Benefit with negative weight (turning it into a "cost"): This accounts for all occurrences across history. If you eat pizza five times in a row, the accumulated cost means you won't go near pizza for a long time.

  2. Recency: This only considers the single most recent occurrence. If you had pizza two weeks ago, it doesn't matter if you had it every day before that - the recency reason only sees that it's been two weeks.

In real-world scenarios, you'd probably use both benefit and recency together. A benefit-based cost would align with how your memory naturally works - food you've had a lot recently feels less appealing, with that feeling slowly fading over time. Recency, on the other hand, helps surface options that haven't come up in a while but deserve consideration.

This combination becomes especially valuable with large collections. If you had 100 recipes in your cookbook, preference alone might mean you cycle through your 20 favorite recipes endlessly, never touching the other 80 even though you generally enjoy them. A benefit reason would help rotate through them, but a recency reason specifically highlights recipes that have fallen out of your regular rotation.

For this example, we're keeping it simpler by using only recency reasons to clearly demonstrate how they work. The assumption is that you don't mind eating the same foods repeatedly, but want the system to encourage variety over time.

Example Notes

This example uses hardcoded dates that made sense when created (October 24, 2025). By the time you load this example, those dates will likely be significantly out of date - if you load it a month later, the recency calculations will show very high values as if nothing has been eaten for a month. The recency reasons depend on the actual dates, unlike the fairer dice example where time doesn't matter. In the future, relative dates might be implemented for these examples to keep them fresh.

Collection

{
  "guid": "0d272ebb-ca28-4b7d-b116-d19e6af01bcd",
  "name": "Food variety",
  "schema": {
    "idProperty": "Food",
    "properties": [
      {
        "name": "Food",
        "type": "string",
        "label": ""
      },
      {
        "name": "Cuisine",
        "type": "string",
        "label": ""
      },
      {
        "name": "Preference",
        "type": "number",
        "label": ""
      }
    ]
  },
  "items": [
    {
      "Food": "Pizza",
      "Cuisine": "Italian",
      "Preference": 8
    },
    {
      "Food": "Burger",
      "Cuisine": "American",
      "Preference": 9
    },
    {
      "Food": "BBQ Ribs",
      "Cuisine": "American",
      "Preference": 7
    },
    {
      "Food": "Mac and Cheese",
      "Cuisine": "American",
      "Preference": 8
    },
    {
      "Food": "Fried Chicken",
      "Cuisine": "American",
      "Preference": 9
    },
    {
      "Food": "Hot Dog",
      "Cuisine": "American",
      "Preference": 6
    },
    {
      "Food": "Grilled Cheese",
      "Cuisine": "American",
      "Preference": 7
    },
    {
      "Food": "Tacos",
      "Cuisine": "Mexican",
      "Preference": 10
    },
    {
      "Food": "Burritos",
      "Cuisine": "Mexican",
      "Preference": 9
    },
    {
      "Food": "Quesadilla",
      "Cuisine": "Mexican",
      "Preference": 8
    },
    {
      "Food": "Pad Thai",
      "Cuisine": "Thai",
      "Preference": 9
    },
    {
      "Food": "Green Curry",
      "Cuisine": "Thai",
      "Preference": 7
    },
    {
      "Food": "Bibimbap",
      "Cuisine": "Korean",
      "Preference": 8
    },
    {
      "Food": "Sushi",
      "Cuisine": "Japanese",
      "Preference": 10
    },
    {
      "Food": "Ramen",
      "Cuisine": "Japanese",
      "Preference": 9
    }
  ]
}

History

{
  "guid": "1acf1229-7e0a-46a9-9986-1a626470e0c7",
  "name": "Food variety",
  "schema": {
    "properties": [
      {
        "name": "Food",
        "type": "collection",
        "label": "",
        "collectionGuid": "0d272ebb-ca28-4b7d-b116-d19e6af01bcd"
      }
    ]
  },
  "items": [
    {
      "id": "49d847f9-9f8e-4205-a02b-9f2b0776b5f3",
      "timestamp": "2025-10-23",
      "Food": "Burritos"
    },
    {
      "id": "7731c5c3-c2e9-49e7-a22c-8e2833331af0",
      "timestamp": "2025-10-22",
      "Food": "Fried Chicken"
    },
    {
      "id": "c2cbac33-8d2e-4b00-87b8-c23915b73962",
      "timestamp": "2025-10-21",
      "Food": "Bibimbap"
    },
    {
      "id": "8f99def4-791c-4e04-8bf2-76f8cf2b9957",
      "timestamp": "2025-10-20",
      "Food": "Burger"
    },
    {
      "id": "e11627a5-85db-4e2d-89f8-7a7af0827d87",
      "timestamp": "2025-10-19",
      "Food": "Sushi"
    },
    {
      "id": "7daea7e4-2829-4844-b079-30a9a6e009e6",
      "timestamp": "2025-10-17",
      "Food": "Pizza"
    },
    {
      "id": "2289c49a-5879-4c68-9790-db149ad911c2",
      "timestamp": "2025-10-15",
      "Food": "Tacos"
    },
    {
      "id": "9e08db74-fd22-450a-bfb6-dc35c09b42f5",
      "timestamp": "2025-10-13",
      "Food": "Pad Thai"
    },
    {
      "id": "28420759-8475-41e2-8272-2c70492190f4",
      "timestamp": "2025-10-12",
      "Food": "Tacos"
    },
    {
      "id": "4961707c-3f85-49ea-bd3e-75ad50ce22db",
      "timestamp": "2025-10-11",
      "Food": "Pad Thai"
    },
    {
      "id": "3a8cc366-57bc-4de7-bc59-d4aa3e786720",
      "timestamp": "2025-10-09",
      "Food": "Grilled Cheese"
    },
    {
      "id": "6da62e7b-5f5a-423a-9b21-7852494a5a50",
      "timestamp": "2025-10-08",
      "Food": "Quesadilla"
    },
    {
      "id": "d9115e23-7d26-4f80-bf8b-a08763c3fd0e",
      "timestamp": "2025-10-06",
      "Food": "Burger"
    }
  ]
}

Choice

{
  "guid": "9de36663-8abd-455d-beac-4cee9eebeeaa",
  "name": "Food variety",
  "collectionGuid": "0d272ebb-ca28-4b7d-b116-d19e6af01bcd",
  "historyGuid": "1acf1229-7e0a-46a9-9986-1a626470e0c7",
  "reasons": [
    {
      "name": "Preference",
      "weight": 1,
      "type": "property",
      "properties": {
        "name": "Preference"
      }
    },
    {
      "name": "Recent Cuisine",
      "weight": 1,
      "type": "recency",
      "properties": {
        "name": "Cuisine",
        "default": 20
      },
      "scaling": 0.5
    },
    {
      "name": "Recent Food",
      "weight": 1,
      "type": "recency",
      "properties": {
        "default": 20
      },
      "scaling": 0.5
    }
  ]
}