Advertisement
pascallius

Untitled

Apr 11th, 2024
836
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.54 KB | None | 0 0
  1. import streamlit as st
  2. import requests
  3. import matplotlib.pyplot as plt
  4.  
  5.  
  6. # Edamam API credentials
  7. EDAMAM_APP_ID = 'b43bfd1e'
  8. EDAMAM_APP_KEY = '52c88b2f791a5ddecbecf76a970d8a13'
  9.  
  10.  
  11. def get_recipes(food, calories_max, include_ingredient=None, exclude_ingredient=None, num_recipes=1):
  12.  
  13.     # The url with the inserted API credentials
  14.     url = f"https://api.edamam.com/search?q={food}&app_id={EDAMAM_APP_ID}&app_key={EDAMAM_APP_KEY}"
  15.  
  16.     # get the response back and save the outputed information in a list data
  17.     response = requests.get(url)
  18.     data = response.json()
  19.  
  20.     # If nothing was found return none
  21.     if 'hits' not in data or not data['hits']:
  22.         return None
  23.  
  24.     # Filter recipes based on criteria given by user
  25.     recipes = data['hits']
  26.     filtered_recipes = []
  27.  
  28.  
  29.     # go over all recipes which match criteria
  30.     for hit in recipes:
  31.         recipe = hit['recipe']
  32.         ingredients = recipe['ingredientLines']
  33.         calories = recipe['calories']
  34.  
  35.         # Exclude recipes with calories greater than max_calories
  36.         if calories > calories_max:
  37.             continue
  38.  
  39.         # search if any words mentioned in include/exclude are part of the ingredients (even subwords or lower/uppercase)
  40.         if include_ingredient and not any(
  41.                 include_ingredient.lower() in ingredient.lower() for ingredient in ingredients):
  42.             # if not, we go into the next for loop iteration
  43.             continue
  44.  
  45.         if exclude_ingredient and any(exclude_ingredient.lower() in ingredient.lower() for ingredient in ingredients):
  46.             continue
  47.  
  48.         # append them to the list of recipes we want
  49.         filtered_recipes.append(recipe)
  50.  
  51.     # if the list is empty, we return none
  52.     if not filtered_recipes:
  53.         return None
  54.  
  55.     return filtered_recipes[:num_recipes]
  56.  
  57.  
  58. def plot_nutrition(recipe):
  59.     # define the advised daily amount of each ingredient
  60.     daily_sugar = 25  # Example daily sugar amount in grams
  61.     daily_salt = 6  # Example daily salt amount in grams
  62.     daily_energy = 2000  # Example daily calorie amount in kcal
  63.  
  64.     # define a standard font size for better design
  65.     fontsize = 16
  66.     nutrients = recipe['totalNutrients']
  67.  
  68.     # Get sugar, salt, and calorie data
  69.     sugar = nutrients.get('SUGAR', {'label': 'Sugar', 'quantity': 0})
  70.     salt = nutrients.get('SUGAR', {'label': 'Salt', 'quantity': 0})
  71.     energy = nutrients.get('ENERC_KCAL', {'label': 'Energy', 'quantity': 0})
  72.  
  73.     # Calculate percentage of suggested daily amounts
  74.  
  75.     sugar_percent = (sugar['quantity'] / daily_sugar) * 100
  76.     salt_percent = (salt['quantity'] / daily_salt) * 100
  77.     energy_percent = (energy['quantity'] / daily_energy) * 100
  78.  
  79.     banner_color = '#FF6347'  # Red color of the banner
  80.  
  81.     fig, axes = plt.subplots(1, 3, figsize=(20, 6))
  82.     plt.style.use('ggplot')
  83.     # The max is needed such that the counterpart is not negative if the amount is bigger than the suggested daily amount.
  84.     # Sugar Pie Chart
  85.     axes[0].pie([sugar_percent, max(100 - sugar_percent, 0)], labels=['', 'Remaining'], colors=[banner_color, '#20B2AA'],
  86.                 autopct='%1.1f%%',
  87.                 shadow=True, startangle=90, textprops={'fontsize': fontsize}, wedgeprops={'edgecolor': 'black'})
  88.     axes[0].axis('equal')
  89.     axes[0].set_title('Sugar (' + str(round(sugar['quantity'])) + "g/" + str(round(sugar_percent)) + "%)",
  90.                      fontweight='bold', fontsize=fontsize, color='black')
  91.  
  92.     # Salt Pie Chart
  93.     axes[1].pie([salt_percent, max(0, 100 - salt_percent)], labels=['', 'Remaining'],
  94.                 colors=[banner_color, '#20B2AA'], autopct='%1.1f%%',
  95.                 shadow=True, startangle=90, textprops={'fontsize': fontsize}, wedgeprops={'edgecolor': 'black'})
  96.     axes[1].axis('equal')
  97.     axes[1].set_title('Salt (' + str(round(salt['quantity'])) + "g/" + str(round(salt_percent)) + "%)",
  98.                      fontweight='bold', fontsize=fontsize, color='black')
  99.  
  100.     # Calorie Pie Chart
  101.     axes[2].pie([energy_percent, max(0, 100 - energy_percent)], labels=['', 'Remaining'],
  102.                 colors=[banner_color, '#20B2AA'], autopct='%1.1f%%',
  103.                 shadow=True, startangle=90, textprops={'fontsize': fontsize}, wedgeprops={'edgecolor': 'black'})
  104.     axes[2].axis('equal')
  105.     axes[2].set_title('Calories (' + str(round(energy['quantity'])) + "/" + str(round(energy_percent)) + "%)",
  106.                      fontweight='bold', fontsize=fontsize, color='black')
  107.     # Plot the graphs
  108.     st.pyplot(fig)
  109.  
  110.  
  111. # Streamlit main function
  112. def main():
  113.     # Streamlit page title and styling
  114.     st.title("Welcome to DailyCalories!")
  115.     # define different markdown classes for a better more standardized design
  116.     st.markdown(
  117.         """
  118.        <style>
  119.            body {
  120.                background-color: #f0f0f0;
  121.                color: #333333;
  122.                font-family: Arial, sans-serif;
  123.                line-height: 1.6;
  124.            }
  125.            .container {
  126.                max-width: 800px;
  127.                margin: 0 auto;
  128.                padding: 20px;
  129.            }
  130.            .header {
  131.                background-color: #007bff;
  132.                color: white;
  133.                padding: 20px;
  134.                border-radius: 5px;
  135.            }
  136.            .subheader {
  137.                font-size: 20px;
  138.                font-weight: bold;
  139.                margin-bottom: 20px;
  140.            }
  141.            .input {
  142.                margin-bottom: 20px;
  143.            }
  144.            .button {
  145.                background-color: #FF6347;  /* Changed button color to red */
  146.                color: white;
  147.                border: none;
  148.                padding: 10px 20px;
  149.                border-radius: 5px;
  150.                cursor: pointer;
  151.                font-size: 16px;
  152.            }
  153.            .button:hover {
  154.                background-color: #D32F2F;  /* Darker red on hover */
  155.            }
  156.            .image {
  157.                max-width: 100%;
  158.                margin-bottom: 20px;
  159.                border-radius: 5px;
  160.            }
  161.            .share-banner {
  162.                background-color: #FF6347;  /* Red color for the share banner */
  163.                color: white;
  164.                padding: 10px;
  165.                text-align: center;
  166.                margin-top: 20px;
  167.                border-radius: 5px;
  168.            }
  169.            .share-banner a {
  170.                color: white;
  171.                margin: 0 10px;
  172.                font-size: 20px;
  173.            }
  174.        </style>
  175.        """,
  176.         # somehow otherwise we get bugs
  177.         unsafe_allow_html=True
  178.     )
  179.  
  180.     # Streamlit input fields for user input
  181.     st.write("""Find the best recipes tailored to your liking""")
  182.     food_type = st.text_input("Enter a Food Type:", "Pasta")
  183.     max_calories = st.number_input("Enter Maximum Calories:", min_value=0, step=100, value=1500)
  184.     include_ingredient = st.text_input("Include Ingredient (optional):")
  185.     exclude_ingredient = st.text_input("Exclude Ingredient (optional):")
  186.     num_recipes = st.number_input("Number of Recipes to Show:", min_value=1, step=1, value=5)
  187.  
  188.     # Button to trigger recipe search
  189.     if st.button("Find Recipes", key='find_recipes_button'):
  190.         # Call the get_recipes function to fetch recipes
  191.         recipes = get_recipes(food_type, max_calories, include_ingredient, exclude_ingredient, num_recipes)
  192.         # Only do it if recipes is not none, if it were, it means that we found no recipes
  193.         if recipes:
  194.             # Loop over all recipes and put them into an expander
  195.             for recipe in recipes:
  196.                 with st.expander(label=recipe['label']):
  197.                     # Display the recipe image
  198.                     st.markdown(f'<p style="text-align: center">><img src="{recipe["image"]}" class="image">', unsafe_allow_html=True)
  199.                     # Display the list of ingredients
  200.                     st.subheader("Ingredients:")
  201.                     for ingredient in recipe['ingredientLines']:
  202.                         st.write("-" + ingredient) #put a "-" infront for a better design
  203.  
  204.                     # Display nutrition information and plot
  205.                     st.subheader("In comparison to the suggested daily intake:")
  206.                     plot_nutrition(recipe)
  207.  
  208.                     # Display a link to the full recipe
  209.                     st.markdown("Find this recipe "+f'[here]({recipe["url"]})')
  210.  
  211.                     # Create share message for each recipe
  212.                     share_message = f"Check out this recipe: {recipe['label']}! It's so delicious! What an amazing site!"
  213.  
  214.                     # Social media sharing links, LinkedIn does not work anymore
  215.                     st.markdown(f"""<div class="share-banner">
  216.                                        Share this recipe:
  217.                                        <a href="https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fdailycalories.com&quote={share_message}" target="_blank">Facebook</a>
  218.                                        <a href="https://twitter.com/intent/tweet?text={share_message}&url=http%3A%2F%2Fdailycalories.com" target="_blank">Twitter</a>
  219.                                        <a href="https://www.linkedin.com/sharing/share-offsite/?url=http%3A%2F%2Fdailycalories.com&summary={share_message}" target="_blank">LinkedIn</a>
  220.                                    </div>""", unsafe_allow_html=True)
  221.         else:
  222.             # Error message if no recipes found
  223.             st.error("No recipes found. Please try different criteria.")
  224.  
  225.  
  226. # Run the Streamlit app
  227. if __name__ == '__main__':
  228.     main()
  229.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement