Background

I recently read Michael Grothaus's article on his positive experiences with giving up refined sugar. Reading this article convinced me that abstaining from sugar was a good idea, and my doctor was enthusiastic about the idea.

In the pursuit of minimizing my refined/added sugar consumption, I have two additional considerations. First, I don't cook and I have no interest in learning. Second, I'm not concerned about minimizing calories because I'm about 6'2", around 200 lbs, and my favorite way to exercise is lifting weights (bro). I think I need around 3000 calories per day to maintain my regimen, but I've never rigorously calculated it. I usually just eat until I feel full.

As anyone who has tried to quit refined sugar knows, it is hard to find food that does not contain it -- especially at restaurants. Scouring the internet, I've found endless articles and blog posts about how to cook food without sugar. To belabor the point, I'm happy for these people but I don't care to learn how to cook. Changing a single lifestyle habit such as consuming no refined/added sugar is difficult enough on its own. Changing two (eliminating sugar and cooking instead of going out) is a (wait for it) *recipe* for failure.

Instead of manually looking over menus and nutrition data for the places I patronize, I decided to build some tools to help with the following analysis.

I should make the disclaimer that I am absolutely not a dietician nor a physician and so you should take the following analysis with a grain of salt (heh). The responsible thing to do is to talk to your doctor if you have concerns about how your diet might be affecting your health.

The American Heart Association recommends that women consume no more than 100 calories per day of added sugars and men consume no more than 150 calories per day of added sugars. These values work out to about 20g for women and 30g for men, assuming (lets call it) a specific energy of 5cal/g for sugar.

Its also very important to note that the American Heart Association makes a distinction between naturally occuring sugars and added sugar:

Are all sugars bad?

No, but added sugars add calories and zero nutrients to food. Adding a limited amount of sugars to foods that provide important nutrients—such as whole-grain cereal, flavored milk or yogurt—to improve their taste, especially for children, is a better use of added sugars than nutrient-poor, highly sweetened foods.

My conclusion from this statement: you could do worse than to eat 1000 calories of fresh blueberries.

Unfortunately, if you are someone who wants to limit their added/refined sugar consumption, there is no US Federal regulation requiring manufacturers to include information about the amount of added vs. naturally occuring sugar in a food product. From what I've read, one can get an idea of the source of sugar in a food product by reading the list of ingredients; if the word "sugar" appears in the list, chances are that sugar is refined. For example, a giant 32oz container of Dannon plain yogurt contains 12g of sugar per serving, which seems like a lot in light of the American Heart Association recommendations above. However, reading the ingredients list shows this yogurt is made only from milk and yogurt cultures. Thus, this food product contains no added sugar (nevertheless, you probably shouldn't eat the whole 32oz in one sitting).

Analysis

The six restaurants I frequently patronize fall into two main categories: burger places and "Mexican". There are a mix of the more legacy fast-food places like McDonald's, Wendy's, (and to perhaps a lesser extent) Taco Bell. The rest, Five Guys, Chipotle, and Qdoba, are upstart fast casual.

I first wanted to get a sense of the sugar in each restaurant's menu. I downloaded the nutrition information of each restaurant's entire menu using the Nutritionix API and attempted to plot a histogram, but I soon found that each restaurant's menu didn't yield an apples-to-apples comparison. Some restaurants included beverages, condiments, etc. while others did not. Therefore, I categorized the menu items of each restaurant by adding category data to each database element. The categories I used were beverage, dessert, condiment, side, and entree. Note that I did not categorize menu items according to meal, i.e. breakfast, lunch, and dinner. Once the items were categorized, I was able to plot histograms of the entree menu items for each restaurant; those histograms are given below.

In [1]:
# Initialize environment
%matplotlib inline
import matplotlib.pyplot as plt
import json
import sqlite3
import minimum_sugar
import numpy as np

database_filename = "menu_data.sqlite3"

# I want the names in the following order
restaurant_names = ["Wendy's",
                    "McDonald's",
                    "Five Guys",
                    "Qdoba",
                    "Taco Bell",
                    "Chipotle",]
In [2]:
with sqlite3.connect(database_filename) as conn:
    cursor = conn.cursor()
    
    # Determine max sugar to properly scale plots
    cursor.execute("SELECT MAX(nf_sugars) FROM menu_data WHERE menu_category = 'entree'")
    sugar_max = cursor.fetchall()
    sugar_max = sugar_max[0][0]
    
    # Plot results
    for restaurant_name in restaurant_names:
        cursor.execute("SELECT nf_sugars FROM menu_data WHERE menu_category = 'entree' AND brand_name = ?", (restaurant_name,))
        sugars = cursor.fetchall()
        
        fig = minimum_sugar.menu_histogram(sugars, x_max=sugar_max, param_name="Sugar [g]", title=restaurant_name)
        plt.show()

Maximum sugar

Perhaps not surprisingly, the individual menu items featuring the maximum amount of sugar are offered by Wendy's and McDonald's. Wendy's is the winner in this category with a healthy sounding menu item: "Apple Pecan Chicken Salad, Full Size" containing 40g of sugar. I wanted to give Wendy's the benefit of the doubt and believe that the sugar comes from the fruit. Unfortunately, Wendy's website features so much unnecessary HTML bling that I wasn't able to find the ingrediants for this menu item within a single click. This poor website design choice soured my positive feelings about Wendy's and now I assume they are trying to obfuscate their nutrition information because they have something to hide.

In [3]:
minimum_sugar.print_max_sugar_menu_item(database_filename, "Wendy's")
Max sugar: 40
Item Name: Apple Pecan Chicken Salad, Full Size

The most sugar-rich menu items for McDonald's are the Big Breakfast With Hotcakes (Large Size Biscuit), Big Breakfast With Hotcakes And Egg Whites (Regular Biscuit), and Big Breakfast With Hotcakes (Regular Size Biscuit) with 17g each. Note that Wendy's has nine entree menu items with sugar greater than McDonald's Big Breakfast, listed below.

In [4]:
mcd_txt = "Maximum sugar situation at McDonald's:"
print mcd_txt
print len(mcd_txt) * "="
minimum_sugar.print_max_sugar_menu_item(database_filename, "McDonald's")
Maximum sugar situation at McDonald's:
======================================
Max sugar: 17
Item Name: Big Breakfast With Hotcakes (Large Size Biscuit)
Max sugar: 17
Item Name: Big Breakfast With Hotcakes And Egg Whites (Regular Biscuit)
Max sugar: 17
Item Name: Big Breakfast With Hotcakes (Regular Size Biscuit)
In [5]:
wen_vs_mcd = "Wendy's menu items with more sugar than max. McDonald's item"
print wen_vs_mcd
print len(wen_vs_mcd) * "="

with sqlite3.connect(database_filename) as conn:
    select_txt = """
        SELECT item_name, nf_sugars 
            FROM menu_data 
            WHERE nf_sugars > 17 
                AND brand_name = 'Wendy''s' 
                AND menu_category = 'entree'
            ORDER BY nf_sugars DESC
        """
    
    cursor = conn.cursor()       
    cursor.execute(select_txt)
    for return_txt in cursor.fetchall():
        print return_txt[0] + ": " + str(return_txt[1])
Wendy's menu items with more sugar than max. McDonald's item
============================================================
Apple Pecan Chicken Salad, Full Size: 40
Steel-Cut Oatmeal with Cranberries and Pecans: 33
Steel-Cut Oatmeal with Apples and Caramel: 26
BBQ Ranch Chicken Salad, Full Size: 26
Pulled Pork Sandwich w/ Spicy BBQ: 25
Pulled Pork Sandwich w/ Sweet BBQ: 23
Apple Pecan Chicken Salad, Half Size: 22
Steel-Cut Oatmeal with Summer Berries: 20
Asian Cashew Chicken Salad, Full Size: 18

Of the burger places, Five Guys has the lowest ceiling on sugar. Unfortunately for the vegetarians out there, the two menu items with 14g sugar are the Veggie Sandwich and Cheese Veggie Sandwich. I've never ordered either of these sandwiches (nor did I realize they exist), but my guess is the sugar comes from the bun and ketchup -- removing those components should lower the total sugar. On the other hand, removing the bun from these sandwiches leaves you with a pile of vegetables, at which point you should probably just head over to Chopt. In fact, are there any vegetarians that go to Five Guys for food?

In [6]:
minimum_sugar.print_max_sugar_menu_item(database_filename, "Five Guys")
Max sugar: 14
Item Name: Veggie Sandwich
Max sugar: 14
Item Name: Cheese Veggie Sandwich

Looking at the histograms, it seems that Chipotle's menu has the lowest amount of sugar per menu item. This conclusion is a little deceiving: the menu items listed for Chipotle are actually components used to assemble menu items such as delicious burritos. The story is similar for Qdoba. The Sofritas has the most sugar at 5g, but there's no mention of sugar in the list of ingrediants for this item. My guess is the sugar comes in with the soybeans.

In [7]:
minimum_sugar.print_max_sugar_menu_item(database_filename, "Chipotle")
Max sugar: 5
Item Name: Sofritas

Taco Bell has 9 entree menu items tied for the most sugar (7g). In list form:

Generally speaking, the burger places (McDonald's, Wendy's, and Five Guys) have a wider distribution in terms of sugar than the "Mexican" places.

In [8]:
minimum_sugar.print_max_sugar_menu_item(database_filename, "Taco Bell")
Max sugar: 7
Item Name: Biscuit Taco - Bacon, Egg & Cheese
Max sugar: 7
Item Name: Biscuit Taco - Sausage, Egg & Cheese
Max sugar: 7
Item Name: Biscuit Taco
Max sugar: 7
Item Name: Fiesta Taco Salad
Max sugar: 7
Item Name: Biscuit Taco - Sausage & Cheese
Max sugar: 7
Item Name: Fiesta Taco Salad - Chicken
Max sugar: 7
Item Name: Fiesta Taco Salad - Beef
Max sugar: 7
Item Name: Fiesta Taco Salad - Steak
Max sugar: 7
Item Name: Biscuit Taco - Egg & Cheese

Minimum sugar vs. calories

Its possible to calculate things like average and standard deviation for the histograms above, but I don't see the utility in that information. Nobody goes to a restaurant and selects random items off the menu. My rule of thumb is to not order anything with more than 3g of sugar, and zero sugar is preferred. Using this rubric, the restaurants I considered have the following number of menu items at that part of the distribution:

In [9]:
for brand_name in restaurant_names:
    with sqlite3.connect(database_filename) as conn:
        select_txt = """
            SELECT COUNT(item_name) 
            FROM menu_data 
            WHERE brand_name = ?
            AND menu_category = 'entree'
            AND nf_sugars < 3
            """
        cursor = conn.cursor()
        cursor.execute(select_txt, (brand_name, ))
        num_items = cursor.fetchone()
        
        print brand_name + ": " + str(num_items[0])
Wendy's: 17
McDonald's: 14
Five Guys: 10
Qdoba: 67
Taco Bell: 32
Chipotle: 19

As I mentioned above, I am interested in consuming more calories than someone smaller or with a different exercise regimen. Thus, my visualization of interest is the histogram of calories for the menu items containing less than three grams of sugar.

In [10]:
with sqlite3.connect(database_filename) as conn:
    # Uniformly scale the horizontal axis on all plots
    select_txt = """
        SELECT MAX(nf_calories) 
        FROM menu_data 
        WHERE menu_category = 'entree'
        AND nf_sugars < 3
        """
    cursor = conn.cursor()
    cursor.execute(select_txt)
    
    calories_max = cursor.fetchone()[0]
    
    # Plot results
    select_txt = """
        SELECT nf_calories
        FROM menu_data
        WHERE menu_category = 'entree'
        AND brand_name = ?
        AND nf_sugars < 3
        """

    for restaurant_name in restaurant_names:
        cursor.execute(select_txt, (restaurant_name, ))
        calories = cursor.fetchall()
        
        fig = minimum_sugar.menu_histogram(calories, x_max=calories_max, param_name="Calories", title=restaurant_name)
        plt.show()

Astonishingly, McDonald's features a menu item with less than 3g sugar and nearly 2000 calories (!) -- the 40 piece Chicken McNuggets. I suspect McDonald's intended this menu item to be purchased for parties and tailgates as opposed to a meal for an individual. McDonald's 20 piece Chicken McNuggets is the runner-up in terms of calories with exactly half: 940 calories.

In [11]:
with sqlite3.connect(database_filename) as conn:
    select_txt = """
        SELECT item_name, nf_calories 
        FROM menu_data
        WHERE brand_name = 'McDonald''s'
        AND nf_sugars < 3
        ORDER BY nf_calories DESC
        """
    cursor = conn.cursor()
    cursor.execute(select_txt)

    for item in cursor.fetchall()[:2]:
        print item[0] + ": " + str(item[1])
Chicken McNuggets (40 Piece): 1880
Chicken McNuggets (20 Piece): 940

Everything else is around 500 calories or less. All the menu items with less than 3g sugar are printed below, sorted by restaurant and calories (high to low).

In [12]:
with sqlite3.connect(database_filename) as conn:
    select_txt = """
        SELECT item_name, nf_calories, nf_sugars
        FROM menu_data
        WHERE brand_name = ?
        AND menu_category = 'entree'
        AND nf_sugars < 3
        ORDER BY nf_calories DESC
        """
    cursor = conn.cursor()
    
    for brand_name in restaurant_names:
        cursor.execute(select_txt, (brand_name, ))
        print brand_name
        print "=" * len(brand_name)
        for item in cursor.fetchall():
            print item[0] + ": " + str(item[1]) + "cal, " + str(item[2]) + "g sugar"
            
        print "\r"
Wendy's
=======
10-Piece Spicy Chicken Nuggets: 470cal, 0g sugar
10-Piece Chicken Nuggets: 450cal, 0g sugar
Crispy Chicken Caesar Wrap: 410cal, 1g sugar
Homestyle Chicken Go Wrap: 340cal, 1g sugar
6-Piece Spicy Chicken Nuggets: 280cal, 0g sugar
Spicy Chicken Breast: 270cal, 0g sugar
Sausage & Egg Burrito: 270cal, 1g sugar
Homestyle Chicken Breast: 270cal, 1g sugar
6-Piece Chicken Nuggets: 270cal, 0g sugar
Caesar Side Salad: 250cal, 2g sugar
1/4 lb. Hamburger Patty: 240cal, 0g sugar
4-Piece Spicy Chicken Nuggets: 190cal, 0g sugar
4-Piece Chicken Nuggets: 180cal, 0g sugar
Premium Cod: 180cal, 0g sugar
Crispy Chicken Patty: 170cal, 0g sugar
Grilled Chicken Breast: 130cal, 0g sugar
Jr. Hamburger Patty: 110cal, 0g sugar

McDonald's
==========
Chicken McNuggets (40 Piece): 1880cal, 1g sugar
Chicken McNuggets (20 Piece): 940cal, 0g sugar
Sausage Biscuit With Egg (Regular Size Biscuit): 510cal, 2g sugar
Chicken McNuggets (10 Piece): 470cal, 0g sugar
Sausage McMuffin With Egg: 450cal, 2g sugar
Sausage Biscuit (Regular Size Biscuit): 430cal, 2g sugar
Sausage McMuffin With Egg Whites: 400cal, 2g sugar
Sausage McMuffin: 370cal, 2g sugar
Chicken Selects (3 Pc): 370cal, 0g sugar
Sausage Burrito: 300cal, 2g sugar
Ranch Snack Wrap (Grilled): 290cal, 2g sugar
Chicken McNuggets (6 Piece): 280cal, 0g sugar
Chicken & Fish Chicken McNuggets (4 piece): 190cal, 0g sugar
Side Salad: 15cal, 1g sugar

Five Guys
=========
Bunless Cheeseburger: 580cal, 1g sugar
Bunless Bacon Burger: 520cal, 0g sugar
Bunless Bacon Cheese Dog: 440cal, 1g sugar
Bunless Hamburger: 440cal, 0g sugar
Bunless Bacon Dog: 370cal, 0g sugar
Bunless Little Bacon Cheeseburger: 370cal, 1g sugar
Bunless Cheese Dog: 360cal, 1g sugar
Bunless Little Bacon Burger: 300cal, 0g sugar
Bunless Little Cheeseburger: 290cal, 1g sugar
Bunless Little Hamburger: 220cal, 0g sugar

Qdoba
=====
Handmade Tortilla Chips: 560cal, 2g sugar
Shredded Cheese - Quesadilla: 440cal, 1g sugar
Handmade Tortilla Chips - Kids Meal: 280cal, 1g sugar
Whole Wheat Flour Tortilla: 260cal, 2g sugar
Whole Wheat - Smothered Burrito: 250cal, 2g sugar
Seasoned Ground Beef: 240cal, 0g sugar
Shredded Cheese - Breakfast Burrito: 220cal, 0g sugar
Grilled Steak: 200cal, 0g sugar
Shredded Beef: 190cal, 0g sugar
3-Cheese Queso: 190cal, 1g sugar
Cilantro Lime Rice: 190cal, 0g sugar
Grilled Chicken: 190cal, 0g sugar
Brown Rice: 170cal, 1g sugar
Shredded Cheese - Burritos: 160cal, 0g sugar
Grilled Chicken - Breakfast Burrito: 160cal, 0g sugar
Queso Diablo: 160cal, 1g sugar
Pulled Pork: 160cal, 1g sugar
Black Beans: 140cal, 1g sugar
Pulled Pork - Taco Salads: 140cal, 1g sugar
Pinto Beans: 130cal, 0g sugar
Guacamole: 130cal, 0g sugar
Seasoned Ground Beef - Craft 2: 120cal, 0g sugar
Roasted Chile Corn, Mild - Chips and Dip: 110cal, 1g sugar
Shredded Cheese: 110cal, 0g sugar
Grilled Steak - Craft 2: 100cal, 0g sugar
Shredded Beef - Craft 2: 100cal, 0g sugar
3-Cheese Queso - Burritos: 100cal, 1g sugar
Cilantro Lime Rice - Craft 2, Smothered Burrito: 100cal, 0g sugar
Grilled Chicken - Craft 2: 100cal, 0g sugar
Tortilla Soup Mexican Gumbo: 90cal, 2g sugar
Brown Rice - Craft 2, Smothered Burrito: 90cal, 1g sugar
Pulled Pork - Craft 2: 80cal, 1g sugar
Shredded Cheese - Smothered Burrito: 80cal, 0g sugar
Seasoned Ground Beef - Tacos: 80cal, 0g sugar
Queso Diablo - Burritos: 80cal, 1g sugar
Grilled Steak - Tacos: 70cal, 0g sugar
Pinto Beans - Craft 2, Smothered Burritos: 70cal, 0g sugar
Crispy Corn Tortilla Strips Mexican Gumbo: 70cal, 0g sugar
Grilled Chicken - Tacos: 70cal, 0g sugar
Black Beans - Craft 2, Smothered Burrito: 70cal, 0g sugar
Roasted Chile Corn, Mild: 60cal, 1g sugar
Shredded Cheese - Tacos: 60cal, 0g sugar
Crispy Taco Shell: 60cal, 0g sugar
Shredded Beef - Tacos: 60cal, 0g sugar
Pulled Pork - Tacos: 50cal, 0g sugar
Tortilla Soup: 45cal, 1g sugar
Sour Cream - Breakfast Burrito: 45cal, 2g sugar
Roasted Chile Corn, Mild - Craft 2, Taco Salads: 30cal, 0g sugar
Roasted Chile Corn, Mild - Tacos: 20cal, 0g sugar
Salsa Roja, Hot: 20cal, 2g sugar
Pico de Gallo, Mild - Chips and Dip: 20cal, 0g sugar
Fiery Habanero Salsa, Extra Hot: 20cal, 2g sugar
Sour Cream - Tacos: 20cal, 1g sugar
Mango Salsa, Seasonal - Craft 2, Tacos Salads: 15cal, 2g sugar
Salsa Verde, Medium: 15cal, 1g sugar
Salsa Roja, Hot - Craft 2, Taco Salads: 10cal, 1g sugar
Pico de Gallo, Mild: 10cal, 0g sugar
Fiery Habanero Salsa, Extra Hot - Craft 2, Taco Salads: 10cal, 1g sugar
Mango Salsa, Seasonal - Tacos: 10cal, 2g sugar
Salsa Verde, Medium - Craft 2, Taco Salads: 10cal, 1g sugar
Sour Cream - Smothered Burrito: 10cal, 0g sugar
Pico de Gallo, Mild - Tacos: 5cal, 0g sugar
Salsa Verde, Medium - Tacos: 5cal, 0g sugar
Fiery Habanero Salsa, Extra Hot - Tacos: 5cal, 1g sugar
Pico de Gallo, Mild - Craft 2, Taco Salads: 5cal, 0g sugar
Salsa Roja, Hot - Tacos: 5cal, 1g sugar
Lettuce: 5cal, 0g sugar

Taco Bell
=========
Cheesy Burrito - Steak & Egg: 480cal, 2g sugar
Chili Cheese Burrito (regional): 370cal, 2g sugar
Triple Layer Nachos: 320cal, 2g sugar
Double Decker&reg; Taco: 320cal, 2g sugar
A.M. Grilled Taco - Sausage: 280cal, 1g sugar
Double Tostada: 270cal, 2g sugar
Meximelt&reg;: 250cal, 2g sugar
Spicy Potato Soft Taco: 240cal, 1g sugar
A.M. Grilled Taco - Bacon: 230cal, 1g sugar
A.M. Grilled Taco: 230cal, 1g sugar
Soft Taco Supreme&reg; - Beef: 210cal, 2g sugar
Beefy Mini Quesadilla: 210cal, 1g sugar
Spicy Tostada: 210cal, 1g sugar
Grilled Steak Soft Taco: 200cal, 2g sugar
Crunchy Taco Supreme&reg;: 190cal, 2g sugar
Fiery Doritos&reg; Locos Taco Supreme&reg;: 190cal, 2g sugar
Nacho Cheese Doritos&reg; Locos Taco Supreme&reg;: 190cal, 2g sugar
Cool Ranch&reg; Doritos&reg; Locos Taco Supreme&reg;: 190cal, 2g sugar
Soft Taco: 190cal, 1g sugar
Soft Taco - Beef: 190cal, 1g sugar
Shredded Chicken Mini Quesadilla: 180cal, 1g sugar
Fiery Doritos&reg; Locos Taco: 170cal, 1g sugar
Cool Ranch&reg; Doritos&reg; Locos Taco: 170cal, 1g sugar
A.M. Grilled Taco - Egg & Cheese: 170cal, 1g sugar
Crunchy Taco: 170cal, 1g sugar
Nacho Cheese Doritos&reg; Locos Taco: 170cal, 1g sugar
Fresco Soft Taco - Beef: 160cal, 2g sugar
Soft Taco - Chicken: 160cal, 1g sugar
Fresco Crunchy Taco - Beef: 150cal, 1g sugar
Fresco Soft Taco - Steak: 150cal, 2g sugar
Fresco Soft Taco - Shredded Chicken: 140cal, 2g sugar
Nacho Cheese Doritos&reg; Chips: 140cal, 0g sugar

Chipotle
========
Flour Tortilla (burrito): 300cal, 0g sugar
Carnitas: 220cal, 0g sugar
Brown Rice: 200cal, 1g sugar
Steak: 190cal, 1g sugar
Cilantro-Lime Rice: 190cal, 0g sugar
Chicken: 180cal, 0g sugar
Barbacoa: 170cal, 0g sugar
Guacamole: 170cal, 0g sugar
Black Beans: 120cal, 1g sugar
Pinto Beans: 120cal, 1g sugar
Cheese: 100cal, 0g sugar
Flour Tortilla (taco): 90cal, 0g sugar
Crispy Taco Shell: 70cal, 1g sugar
Soft Corn Tortilla: 70cal, 0g sugar
Red Tomatillo Salsa: 25cal, 1g sugar
Fajita Veggies: 20cal, 2g sugar
Green Tomatillo Salsa: 20cal, 2g sugar
Romaine Lettuce (salad): 10cal, 1g sugar
Lettuce: 5cal, 0g sugar

The worst offenders? Beverages.

Perhaps not surprisingly, beverages are a great way to consume a lot of sugar over a short period. To make this point, consider the following histogram plots in which each restaurant's entree items appear along with beverages. Please note that Nutritionix had no beverages listed in its database for some of the restaurants in this analysis. I still plot their histograms with the others for the sake of comparison.

In [13]:
with sqlite3.connect(database_filename) as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT MAX(nf_sugars) FROM menu_data WHERE menu_category = 'beverage'")
    sugar_max = cursor.fetchone()[0]
    
    select_txt = """
        SELECT nf_sugars
        FROM menu_data
        WHERE menu_category = ?
        AND brand_name = ?
        """
    
    for brand_name in restaurant_names:
        cursor.execute(select_txt, ("entree", brand_name, ))
        entree_sugars = cursor.fetchall()

        cursor.execute(select_txt, ("beverage", brand_name, ))
        beverage_sugars = cursor.fetchall()
        
        fig = minimum_sugar.menu_histogram(entree_sugars, x_max=sugar_max, param_name="Sugar [g]", title=brand_name, alpha=0.5, label="Entree")
        if len(beverage_sugars) > 0:
            fig = minimum_sugar.menu_histogram(beverage_sugars, x_max=sugar_max, param_name="Sugar [g]", fig=fig, alpha=0.5, label="Beverage")
        
        plt.legend()
        plt.show()

I don't have much to say about beverages except just don't order them. There seems to be no upside.

Remarks

Rules of thumb:

  • If Ron Swanson wouldn't drink it (water, black coffee, scotch), it probably contains sugar. The sugar histograms show that beverages contain lots of sugar.
  • Avoid ketchup. And most other sauces. Mustard is the superior condiment anyway so use it instead. I didn't show the analysis, but typically sauces and dressings contain too much sugar. Anecdotal evidence of the high sugar content of sauces can be seen in the Wendy's pulled pork sandwiches above. On the other hand, eastern NC style barbecue sauce, The One True Barbecue Sauce, is the exception.
  • Order your burger without ketchup and the bun and you should have enough calories with minimal sugar.
  • A lot of low-sugar entree menu items are based on chicken instead of beef.

During the course of this analysis, I was struck by the fact that the legacy/non-fast casual restaurants have a ton of menu items. McDonald's has >350 where Chipotle only has like 25. Granted, Nutritionix had no data on beverage offerings from Chipotle whereas they did have beverages from McDonalds. Nonetheless, McDonalds still has 86 items I categorized as entrees vs. Chipotle's 25.

I can't imagine the amout of complexity that number of menu items adds to the management of the company. I also can't see how McDonalds gets rid of this complexity (i.e. sheds menu items) without alienating the customers these items intended to serve. It seems like this amount of complexity is an accretion over many years and is likely a result of their success. It seems eminently plausible that over the years executives at McDonalds thought, "We are dominating this part of the market which is basically tapped out. In order to experience even more growth, we need to expand into other markets. How do we expand into other markets while leveraging the power of this brand to crush the competition?"

In [14]:
with sqlite3.connect(database_filename) as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT COUNT(item_name) FROM menu_data WHERE brand_name = 'McDonald''s' AND menu_category = 'entree'")
    
    print "Number of McDonald's entree menu items:", str(cursor.fetchone()[0])
Number of McDonald's entree menu items: 86

Source

This repository in which this report was developed is hosted on github.