Skip to content
Project
  • AI Chat
  • Code
  • Report
  • Spinner

    Project: Nutritional Value and Carbon Footprint

    • 2023 Winter/Summer School - University of Hamburg
    • By: Reinaldy Poetra (UHH) and Pooja Tiwari (UHH)

    Research Question:

    1. What is the best food with a low carbon footprint yet provide a high in nutritional value?

    2. Is Kuznet curve true about the ecological aspect? The environmental Kuznets curve (EKC) is a hypothesized relationship between environmental quality and economic development formed an U-Shape curve.

    Note:

    Note that to test the kuznet curve we need a lot of data - in this mini project the goals in this script are:

    1. Generating a kuznet curve as a function of income per capita and enviromental degradation/carbon emission,

    2. Generating nutrition value vs carbon footprint for the main food based on the compiled database, and

    3. Asking the user about the prefference meal as a basis data for testing Kuznet curve (ontinuity of the project).

    Refference:

    • Food and Agricultural Organization of the United Nations Database

    • Harvard T.H. Chan School of Public Health database

    • Health Canada

    • Swedish Food Agency

    Phase I: Import package

    note: essential for running the script!

    #Import package for running the command in this worksheet
    #If you fail to import the modules, please download the modules (-pip) or use conda environment.
    import pandas as pd
    import numpy as np
    import plotly.express as px
    import plotly.graph_objects as go
    

    Phase II: Generating Kuznet Curve

    #Kuznet Curve
    
    #Generating x and y values for kuznet curve plot
    kuznet_data_x = np.arange(-10, 10, 0.01) #np.arange is used for creating range values start from -10 to 10 with 0.01 step
    kuznet_data_y = -kuznet_data_x ** 2 #as kuznet is inverted-u curve (quadratic function), so y-value should be the -(x)^2
    #store the values above into dataframe to make a tidy data
    kuznet_df = pd.DataFrame({"X" : kuznet_data_x,
                              "Y" : kuznet_data_y})
    
    #Generate line plot for kuznet curve via stored dataframe
    fig_kuznet = px.line(data_frame = kuznet_df, #recall the database/dataframe
                       x = "X", #plot the object from dataframe in the x-axis
                       y = "Y", #plot the object from dataframe in the y-axis
                       title = "Kuznet Curve <br><sup>Hyphothesis: inverted U-Shape in the relationship between Income per capita and environmental condition (GHG)</sup>", #title or header
                       labels = {"X": "Income per capita", #labels for x-axis
                                 "Y": "Environmental Degradation" #labels for y-axis
                                 }
                            )
    
    #Customize the layout in the plot
    fig_kuznet.update_layout({"paper_bgcolor" : "white", #change the paper colour to white
                         "plot_bgcolor" : "white", #change the plot background colour to white
                         },
                        showlegend = False #hide the legend
                        )
    
    #customize line style in the plot
    fig_kuznet.update_traces(line_color="black")
    #customize the x-axis syle
    fig_kuznet.update_xaxes(showline=True, linewidth= 2, linecolor="black", range = [-11,11], showgrid=False, showticklabels=False) 
    #customize the y-axis syle
    fig_kuznet.update_yaxes(showline=True, linewidth= 2, linecolor="black", range = [-120,20], showgrid=False, showticklabels=False) 
    
    #add text into the plot
    fig_kuznet.add_trace(go.Scatter(
        x = [0],
        y = [5],
        mode = "text",
        name="Text",
        text = "Turning Point",
        textposition = "top center",
        textfont = dict(size = 14, color = "red")
    ))
    
    #add text into the plot
    fig_kuznet.add_trace(go.Scatter(
        x = [-9],
        y = [-110],
        mode = "text",
        name="Text",
        text = "Low Income",
        textposition = "top center",
        textfont = dict(size = 14, color = "red")
    ))
    
    #add text into the plot
    fig_kuznet.add_trace(go.Scatter(
        x = [9],
        y = [-110],
        mode = "text",
        name="Text",
        text = "High Income",
        textposition = "top center",
        textfont = dict(size = 14, color = "red")
    ))
    
    
    
    fig_kuznet.show()

    Phase III: Nutrient Density vs Greenhouse Gas Emission (Carbon Footprint)

    Import data from csv

    #Transform csv as dataframe
    nd_ghg = pd.read_csv("nd_ghg.csv")
    nd_ghg.head() #print the headers of the dataframe
    nd_ghg.info() #print info to check the data
    print(nd_ghg) #show the data

    Generating Plot Nutrient Density vs Carbon Footprint

    #Plot for Nutrient Density vs Greenhouse Gas Emission (Carbon Footprint)
    
    #Calculate relative nutrition density - 4.00 is the average density of the seafood as refference point
    relative_nd = (nd_ghg["Nutrient density"] / 4) * 100
    nd_ghg["relative_nutrient"] = relative_nd #add the object to dataframe
    
    #Calculate relative greenhouse gas emission - 3.70 is the average GHG of the seafood as the refference point
    relative_ghg = (nd_ghg["GHG (kg CO2e/kg edible)"] / 3.70) * 100
    nd_ghg["relative_ghg"] = relative_ghg #add the object to dataframe
    
    #Generate scatter plot of carbon footprint vs nutrition density in the selected (main) food
    fig_2 = px.scatter(data_frame = nd_ghg, #recall the database/dataframe
                       x = "relative_nutrient", #plot the object from dataframe in the x-axis
                       y = "relative_ghg", #plot the object from dataframe in the y-axis
                       title = "Carbon Footprint vs Nutrient Density <br><sup>The Carbon Footprint and Nutrient Density are diveded by the average seafood's GHG (3.70) and Nutrient Density (4.0)</sup>", #title or header
                       labels = {"relative_nutrient": "Relative Nutrition Value (%)",
                                 "relative_ghg": "Relative Carbon Footprint (%)"
                                 }, #automatic labeling - customize the label
                        #height =700, width = 700, #if want to set the specific size for plot
                        text = "Group name",
                        color = "Group name", #set the color for specific object
                        color_discrete_map={"Cephalopods" : "#67001f",
                                            "Farmed crustaceans" : "#b2182b",
                                            "Farmed salmonids" : "#d6604d",
                                            "Farmed whitefish" : "#f4a582",
                                            "Fished crustaceans" : "#fddbc7",
                                            "Fished whitefish" : "#d1e5f0",
                                            "Bivalves" : "#92c5de",
                                            "Small pelagics" : "#4393c3",
                                            "Large pelagics" : "#2166ac",
                                            "Wild salmon" : "#053061",
                                            "Beef" : "#d73027",
                                            "Chicken" : "#d73027",
                                            "Pork" : "#d73027",
                        }, #color discrete map customizes the color - here I set the color to color-blind friendly for each values manually
                        symbol = "Group name", #set the symbol by specific object/variable
                        symbol_map = {"Cephalopods" : "square",
                                            "Farmed crustaceans" : "square",
                                            "Farmed salmonids" : "square",
                                            "Farmed whitefish" : "square",
                                            "Fished crustaceans" : "square",
                                            "Fished whitefish" : "square",
                                            "Bivalves" : "square",
                                            "Small pelagics" : "square",
                                            "Large pelagics" : "square",
                                            "Wild salmon" : "square",
                                            "Beef" : "x",
                                            "Chicken" : "circle",
                                            "Pork" : "diamond",
                        }, #symbol map custumizes the marker symbol manually, I want to specificy beef, chicken, and pork with different marker/shape
                       )
    
    #Customize layout of the plot
    fig_2.update_layout({"paper_bgcolor" : "white", #change the paper colour to white
                         "plot_bgcolor" : "white", #change the plot background colour to white
                         },
                         showlegend = False, #hide the legend, change True if you want to see the legend
                         legend_title_text = "Group", #set the title for the legend
                         legend = dict(font=dict(size=10)), #set the font size in the legend
                         )
    fig_2.update_traces(marker=dict(size = 16, line=dict(width = 2, color="black"))) #customize the marker style
    fig_2.update_xaxes(showline=False, linewidth= 1, linecolor="black", range = [50, 160],
                       showgrid=True, gridwidth = 1, gridcolor="black", griddash = "dot") #customize the x-axis line style
    fig_2.update_yaxes(showline=False, linewidth=1, linecolor="black", range = [-500, 2000],
                       showgrid=True, gridwidth = 1, gridcolor="black", griddash = "dot") #customize the y-axis line style
    
    #set the quadrant line where x and y = 100%
    fig_2.add_vline(x=100, line_width=2, line_color = "black")
    fig_2.add_hline(y=100, line_width=2, line_color = "black")
    #set the quadrant line where x and y = 0%
    fig_2.add_vline(x=0, line_width=1, line_color = "black", line_dash = "dot")
    fig_2.add_hline(y=0, line_width=1, line_color = "black", line_dash = "dot")
    #Customize text (label) in the plot
    fig_2.update_traces(textposition='top center',
                        textfont=dict(color="black", size = 12),
                        )
    #Show the figure
    fig_2.show()

    Phase IV: Input the question for user data

    #Opening statement
    print("Hello, Moin, and Holà! Thank you very much for checking my script!")
    print("I would love to ask you some questions")
    print("It will be anonymous! and the data is used for testing Kuznet curve!")
    print("Any concern, suggestion, and feedback - please feel free to contact me!")
    #Question base as scalar values
    country = str(input("What country are you from?"))
    income = int(input("How much is your income per month (net income) in US Dollar?"))
    gender = str(input("What is your gender?"))
    year_born = int(input("In what year were you born?"))
    age = 2022 - year_born
    
    #store the user data as library - by transforming scalar values to list using []
    user_data = {"country" : [country],
                 "income_month_net" : [income],
                 "gender" : [gender],
                 "year_born" : [year_born],
                 "age" : [age]}
    #store the user data from library to dataframe
    df_user = pd.DataFrame(user_data)
    
    print("Hello! " + str(age) + " years old person from " + str(country) + "! It is my honor to welcome you in my script!")

    Phase V: Game (Simualtion) Preference Meal

    ###Opening and description of the question in the script
    print("Let's play a game!")
    print("I would like to ask you about the food that you will eat daily")
    print("It is not a whole food but just a main component in your food")
    print("Just select the appropriate food that you would like to grab in the give options")
    print("If you are vegan or vegetarian - just pretend that you are omnivore in this question")
    
    ###Question for breakfast
    question_breakfast = str(input("What kind of food that you like for breakfast? beef, pork, chicken, or seafood?"))
    
    #If function to check whether the user fill the answer in manner or not
    if question_breakfast == "beef" or question_breakfast == "chicken" or question_breakfast == "pork" or question_breakfast == "seafood":
          print(question_breakfast)
    else: print("Error! Make sure you type the answer based on the given options")
    
    #create an function "test" with "def" to process the answer from the user into the next phase
    def test(value):
          if value == "seafood":
                return str(input("More specific, what kind of seafood? whitefish, salmon, lobster, bivalve or squid?")) #this code ask the user to specify what kind of seafood
          if value == "beef" or value == "chicken" or value == "pork":
                return value #store the result (value) as final answer from the user
    
    #store the final answer as variable
    breakfast = test(question_breakfast)
    
    
    ###Question for lunch
    question_lunch = str(input("What kind of food that you like for lunch? beef, pork, chicken, or seafood?"))
    
    #If function to check whether the user fill the answer in manner or not
    if question_lunch == "beef" or question_lunch == "chicken" or question_lunch == "pork" or question_lunch == "seafood":
          print(question_lunch)
    else: print("Error! Make sure you type the answer based on the given options")
    
    #create an function "test" with "def" to process the answer from the user into the next phase
    def test(value):
          if value == "seafood":
                return str(input("More specific, what kind of seafood? whitefish, salmon, lobster, bivalve or squid?")) #this code ask the user to specify what kind of seafood
          if value == "beef" or value == "chicken" or value == "pork":
                return value #store the result (value) as final answer from the user
    
    #store the final answer as variable
    lunch = test(question_lunch)
    
    
    ###Question for dinner
    question_dinner = str(input("What kind of food that you like for dinner? beef, pork, chicken, or seafood?"))
    
    #If function to check whether the user fill the answer in manner or not
    if question_dinner == "beef" or question_dinner == "chicken" or question_dinner == "pork" or question_dinner == "seafood":
          print(question_dinner)
    else: print("Error! Make sure you type the answer based on the given options")
    
    #create an function "test" with "def" to process the answer from the user into the next phase
    def test(value):
          if value == "seafood":
                return str(input("More specific, what kind of seafood? whitefish, salmon, lobster, bivalve or squid?")) #this code ask the user to specify what kind of seafood
          if value == "beef" or value == "chicken" or value == "pork":
                return value #store the result (value) as final answer from the user
    
    #store the final answer as variable
    dinner = test(question_dinner)
    
    #print the resume for the user
    print("great! So you would like to have " + breakfast + " for your breakfast" + ", " + lunch + " for your lunch, and " + dinner + " for your dinner")
    
    
    #store the user data as library - by transforming scalar values to list using []
    food= {"breakfast" : [breakfast],
          "lunch" : [lunch],
          "dinner" : [dinner]}
    #store the user data from library to dataframe
    df_food = pd.DataFrame(food)
    #merge to dataframe "user" and "dataframe"
    df_all = pd.concat([df_user, df_food], axis=1) #axis set the dataframe into one row