Yhztro's picture
Update app.py
dfd40d7 verified
import streamlit as st
import pandas as pd
import numpy as np
import gspread
import io
import googleapiclient.discovery
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
import random
import requests
import altair as alt
from PIL import Image
from io import BytesIO
logo_url = "https://www.gradina-slavu.ro/"
logo_path = "https://static.wixstatic.com/media/268e9b_fb1da1f5fc304d15beee1d2e581d5d0c~mv2.png/v1/fill/w_134,h_62,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/nume.png"
# Display the logo with a black background and centered alignment
st.markdown(
f"""
<div style='background-color: rgba(128,128,128,0.4); text-align: center;'>
<a href='{logo_url}' target='_blank'>
<img src='{logo_path}' width='150'>
</a>
</div>
""",
unsafe_allow_html=True,
)
query_params = st.experimental_get_query_params()
# Get the value of a specific parameter
# Display the input value
st.title('RETETE - Selecteaza produse si retete din sidebar ori un meniu de mai jos')
st.write(' ')
sa= gspread.service_account(filename='creds.json')
# Open the Google Sheets file
sh = sa.open_by_url("https://docs.google.com/spreadsheets/d/1GZjbDLYTgRhKHtvgT868ursHYzXXmHF23w86-3KNZN0/edit#gid=489241774")
worksheet=sh.get_worksheet(0)
worksheet1=sh.get_worksheet(1)
worksheet2=sh.get_worksheet(2)
worksheet3=sh.get_worksheet(3)
rows = worksheet.get_all_values()
rows1 = worksheet1.get_all_values()
rows2 = worksheet2.get_all_values()
rows3 = worksheet3.get_all_values()
df=pd.DataFrame(rows)
df1=pd.DataFrame(rows1)
df2=pd.DataFrame(rows2)
df3=pd.DataFrame(rows3)
df2=df2.iloc[1:]
st.sidebar.markdown("---")
st.sidebar.write("In prima sectiune poti alege unul din produsele noastre! Vei primi sugestii de retete pentru el (gramajul este fixat la 100 de grame),recomandam folosirea celei de-a doua sectiuni pentru a-ti contrui meniul!")
if "input_param" in query_params:
input_value = query_params["input_param"][0]
input_value = [input_value]
input_values = [""] + df3.iloc[:, 0].tolist()
st.selectbox("Selecteaza Meniu", input_values)
elif "input_param" not in query_params:
# Get the values from the first column in df3
input_values = [""] + df3.iloc[:, 0].tolist()
input_value = st.selectbox("Selecteaza Meniu", input_values)
#st.write('Nu uita sa deselectezi optiunile din sidebar, in cazul in care meniul nu se afiseaza!', text_color="green")
st.markdown('<span style="color:green">Nu uita sa deselectezi optiunile din sidebar, in cazul in care meniul nu se afiseaza!</span>', unsafe_allow_html=True)
input_value = [input_value] if input_value else []
else:
input_value = []
options=['branza vegetala','dulceata de ardei iute','stevie','rosii cherry','rosii tocate','suc de rosii','rosii cherry uscate in ulei','pesto de busuioc','carne vegetala','pudra de dovleac','zacusca de vinete','zacusca de peste','zacusca de fasole','magiun de prune','hrean in otet','legume uscate']
options.sort()
valori_optime=['2000','280','25','50','70','20','1600','17000','50','5000','75','350','10','120','1.4','1.6','18','2','400','6','6','550','500','1000','15','350','1000','3500','2400','15','2','5','200','3500','300','2000']
selected_option = st.sidebar.radio("Selecteaza un produs", options)
st.sidebar.write("Fiecare cadru de date poate fi derulat la stânga și la dreapta pentru mai multe informații!")
st.experimental_set_query_params()
def select_random_value(df, selected_option):
# Select a random item from the list
selected_item = selected_option
# Find the corresponding values in the dataframe
matching_rows = df[df[3] == selected_item]
corresponding_values = matching_rows[0].tolist()
# Select a random value from the corresponding values
if corresponding_values:
selected_value = random.choice(corresponding_values)
return selected_value
else:
return None
reteta_selectata=select_random_value(df1,selected_option)
d2 = df2.set_index(0).to_dict('index')
d2 = {k: {k2: float(v2) for k2, v2 in v.items()} for k, v in d2.items()}
discarded_keys=['Calorii','Zaharuri','Grasimi saturate','Omega-6','Vit A','Vit C','Vit D','Vit E','Vit K','Pantothenic acid-B5','Choline-B4','Betaine','Sodiu','Cupru','Mangan','Seleniu','Fluor','Cholesterol','Phytosterols']
def select_optimized_keys(d, value, optimals):
optimals = [float(x) for x in optimals]
matching_key = [k for k, v in d.items() if k == value][0]
other_keys = [k for k in d.keys() if k != matching_key]
second_key = random.choice(other_keys)
other_keys.remove(second_key)
third_key = random.choice(other_keys)
return (second_key, third_key, matching_key)
key_options = list(df1[0].unique())
key_options = sorted(key_options)
if '' in key_options:
key_options.remove('')
st.sidebar.markdown("---")
st.sidebar.write("In a doua sectiune poti alege pana la trei retete, gramajele pentru fiecare reteta si bauturile! Vei afla nutrientii consumati in decurs de o masa sau o zi!")
st.sidebar.write("Construieste-ti meniul!")
selected_keys_option = st.sidebar.multiselect("Selecteaza pana la trei retete dorite", key_options)
if selected_keys_option:
selected_keys = list(selected_keys_option)
elif input_value and not pd.isnull(input_value):
if input_value in df3.iloc[:, 0].values:
selected_row = df3[df3.iloc[:, 0] == input_value[0]]
# Store the selected row in a different DataFrame
selected_df = selected_row.copy()
column_values = df3.iloc[:, 0].tolist()
index = column_values.index(input_value[0])
selected_keys = input_value+[df3.iloc[index, 2]]
if df3.iloc[index, 4]:
selected_keys.append(df3.iloc[index, 4])
else:
selected_keys = []
else:
selected_keys = []
# If the user hasn't selected their own keys, use the default function to select random keys
if not selected_keys:
selected_keys = select_optimized_keys(d2, reteta_selectata, valori_optime)
selected_keys = list(selected_keys)
selected_keys.reverse()
def search_values(lst, dct):
result = {}
for item in lst:
for key, value in dct.items():
if item == key:
result[item] = value
return result
# create a dictionary to hold the new dataframes
dfs = {}
# loop through the categories and create a new dataframe for each one
for reteta in selected_keys:
dfs[reteta] = df1[df1[0] == reteta]
dfs2={}
for reteta in selected_keys:
dfs2[reteta] = df1[df1[0] == reteta].iloc[:,6:]
def make_clickable(url):
return f'<a href="{url}" target="_blank">{url}</a>'
final_result=search_values(selected_keys,d2)
Finaldf=pd.DataFrame(final_result)
Finaldf=Finaldf.round(2)
new_index=['Calorii','Carbohidrati','Fibre dietetice','Zaharuri','Grasimi','Grasimi saturate','Omega-3','Omega-6','Proteina','Vit A','Vit C','Vit D','Vit E','Vit K','Thiamin-B1','Riboflavin-B2','Niacin-B3','Vitamina-B6','Folate-B9','Vitamina-B12','Pantothenic acid-B5','Choline-B4','Betaine','Calciu','Fier','Magneziu','Fosfor','Potasiu','Sodiu','Zinc','Cupru','Mangan','Seleniu','Fluor','Cholesterol','Phytosterols']
Finaldf = Finaldf.set_index(pd.Index(new_index))
def add_dict_values(d):
result = {}
keys = set().union(*(d[key].keys() for key in d))
for key in keys:
result[key] = sum(d[k].get(key, 0) for k in d)
return result
valori_meniu_d = add_dict_values(final_result)
valori_meniu = list(valori_meniu_d.values())
# Define the function to subtract two lists
def subtract_lists(list1, list2):
result = []
for i, j in zip(list1, list2):
result.append(max(0, float(i) - float(j)))
return result
# Define the default value of the slider
factors = {
"Option 1": 1,
"Option 2": 2,
"Option 3": 3
}
factor_dict = {}
for col in Finaldf.columns:
default_factor=100
slider_label = f"Alege greutatea meniului pentru {col}, in grame"
slider_key = f"{slider_label}-{default_factor}"
factor1=st.sidebar.slider(label=slider_label, key=slider_key, min_value=0, max_value=750,step=50, value=default_factor)
multiplied_column = Finaldf[col] * factor1/100
Finaldf[col] = multiplied_column
factor_dict[col] = factor1
if not selected_keys_option: # default factor is being used or dict values
if input_value and input_value[0]:
selected_dict = {}
for col_idx in range(0, len(selected_df.columns), 2):
key_col = selected_df.columns[col_idx]
value_col = selected_df.columns[col_idx + 1]
selected_dict[selected_df[key_col].values[0]] = selected_df[value_col].values[0]
for col in Finaldf.columns:
#col
if col in selected_dict:
factor1 = float(selected_dict[col])
#factor1
multiplied_column = Finaldf[col] * factor1/100
Finaldf[col] = multiplied_column
factor_dict[col] = factor1
row_sums = Finaldf.sum(axis=1)
selected_df = pd.DataFrame.from_dict(selected_dict, orient='index', columns=['Value'])
# Add " g" to the values
selected_df['Value'] = selected_df['Value'].astype(str) + ' g'
st.write('Tabel Gramaje Retete')
selected_df
Finaldf['Valori meniu'] = row_sums
else:
default_factor=350
factor1 = default_factor
row_sums = Finaldf.sum(axis=1)
factor_dict = {col: factor1 for col in Finaldf.columns}
Finaldf['Valori meniu'] = row_sums
else:
Finaldf['Valori meniu'] = Finaldf[selected_keys_option].sum(axis=1)
#selectare bautura
bautura_list = sorted(df[df.iloc[:, 1] == 'bautura'].iloc[:, 0].tolist())
selected_bautura_list = st.sidebar.multiselect("Selecteaza bauturi", bautura_list)
bauturi={}
if selected_bautura_list:
for bautura in selected_bautura_list:
filtered_df = df[(df[0] == bautura) & (df[1] == 'bautura')].reset_index(drop=True)
selected_df = filtered_df.iloc[:, 2:].astype(float)
selected_df = selected_df.apply(lambda x: x * 2.5) # multiply by 2.5
selected_df = selected_df.T.rename(columns={0: bautura})
Finaldf[bautura] = selected_df[bautura].values
bauturi[bautura] = selected_df[bautura].fillna(0).values
bauturi_df = pd.DataFrame.from_dict(bauturi, orient='index').T
bauturi_sum = bauturi_df.apply(pd.to_numeric).sum(axis=1)
Finaldf['Valori meniu portii de 100g']=valori_meniu
valori_meniu_factori=Finaldf['Valori meniu'].tolist()
if bauturi_sum.any():
Valori_ramase=subtract_lists(valori_optime,valori_meniu_factori)
Valori_ramase=Valori_ramase-bauturi_sum.values
Valori_ramase = np.maximum(Valori_ramase, 0)
bauturi_sum.index = new_index
Finaldf['Valori bauturi'] = bauturi_sum
Finaldf['Valori meniu si bauturi'] = ((Finaldf['Valori meniu'])+bauturi_sum).round(2)
else:
Valori_ramase=subtract_lists(valori_optime,valori_meniu_factori)
Valori_ramase = np.maximum(Valori_ramase, 0)
Finaldf['Valori meniu si bauturi'] = (Finaldf['Valori meniu']).round(2)
for i in range(len(selected_keys)):
dfs1 = dfs[selected_keys[i]]
dfs1 = pd.DataFrame(dfs1)
images_displayed = False
# update 'path' column with formatted URLs
for index, row in dfs1.iterrows():
image_path = row[6]
if not image_path:
continue
credentials = service_account.Credentials.from_service_account_file('creds.json')
# Build the Google Drive service
drive_service = build('drive', 'v3', credentials=credentials)
# Retrieve image content from Google Drive
request = drive_service.files().get_media(fileId=image_path)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
try:
image = Image.open(fh)
image = image.resize((300,300))
with st.container():
col1, col2, col3 = st.columns([1, 2, 1])
col2.image(image, caption=selected_keys[i], width=300, use_column_width=True)
images_displayed = True
if images_displayed:
dfs1 = dfs1.iloc[:,3:6]
dfs1 = dfs1.reset_index(drop=True)
indexcol = ['Ingrediente', 'Gramaj', 'Preparare']
dfs1.columns = indexcol
new_df = dfs1.copy()
if not selected_keys_option: # default factor is being used or dict values
if input_value and input_value[0]:
selected_dict = {}
for col_idx1 in range(0, len(selected_df.index)):
key = selected_df.index[col_idx1]
value = selected_df.iloc[col_idx1,0]
selected_dict[key] = value.strip(' g')
if selected_keys[i] in selected_dict:
factor2 = float(selected_dict[selected_keys[i]])/100
#st.write("Factor2:", factor2)
new_df['Gramaj'] = (((new_df['Gramaj'].astype(float)*factor2)/ new_df['Gramaj'].astype(float).sum()) * 100).round(2)
new_df['Gramaj/2Portii'] = (new_df['Gramaj'].astype(float) * 2).round(2)
new_df['Gramaj/3Portii'] = (new_df['Gramaj'].astype(float) * 3).round(2)
new_df['Gramaj/4Portii'] = (new_df['Gramaj'].astype(float) * 4).round(2)
else:
factor2 = 3.5
new_df['Gramaj'] = (((new_df['Gramaj'].astype(float)*factor2)/ new_df['Gramaj'].astype(float).sum()) * 100).round(2)
new_df['Gramaj/2Portii'] = (new_df['Gramaj'].astype(float) * 2).round(2)
new_df['Gramaj/3Portii'] = (new_df['Gramaj'].astype(float) * 3).round(2)
new_df['Gramaj/4Portii'] = (new_df['Gramaj'].astype(float) * 4).round(2)
else:
if selected_keys[i] in factor_dict:
#selected_keys[i]
factor2 = factor_dict[selected_keys[i]]/100
new_df['Gramaj'] = (((new_df['Gramaj'].astype(float)*factor2)/ new_df['Gramaj'].astype(float).sum()) * 100).round(2)
new_df['Gramaj/2Portii'] = (new_df['Gramaj'].astype(float) * 2).round(2)
new_df['Gramaj/3Portii'] = (new_df['Gramaj'].astype(float) * 3).round(2)
new_df['Gramaj/4Portii'] = (new_df['Gramaj'].astype(float) * 4).round(2)
indexcol1 = ['Ingrediente', 'Gramaj', 'Gramaj/2Portii', 'Gramaj/3Portii', 'Gramaj/4Portii', 'Preparare']
new_df = new_df.reindex(columns=indexcol1)
st.subheader(selected_keys[i])
#st.write("Dublu-click pe o celulă pentru a vedea textul complet in Preparare.")
#st.write(dfs1,index=False)
pd.set_option('display.max_colwidth', None)
new_df_excluded = new_df.drop(columns=["Preparare"])
# Display the modified DataFrame
st.dataframe(new_df_excluded)
max_length = 800
# Truncate the text in the DataFrame columns
new_df_truncated = new_df.apply(lambda x: x.str[:max_length] + '...' if x.dtype == "object" else x)
new_df_truncated = new_df_truncated.dropna(axis=0, how='all')
# Display the DataFrame with tooltips
st.table(new_df_truncated[['Preparare']])
else:
st.warning(f"No image found for {selected_keys[i]}")
except:
continue
Finaldf['Valori ramase dupa portiile selectate']=Valori_ramase.round(2)
Finaldf['Valori Optime']=valori_optime
st.write('Tabel cu valori ramase, valori totale per meniu si valori optime de consum')
st.write(Finaldf)
Valori_normate = [(float(valori_optime[i]) - Valori_ramase[i]) / float(valori_optime[i]) for i in range(len(valori_optime))]
Valori_ramase_normate=[ Valori_ramase[i] / float(valori_optime[i]) for i in range(len(valori_optime))]
chartdf = pd.DataFrame({
'Procente ramase de consumat':pd.Categorical(new_index, categories=new_index),
'max_values':Valori_normate,
'Procente': Valori_ramase_normate,
})
# Create a Categorical datatype for the x-axis
x_scale = alt.Scale(domain=new_index, zero=False)
# Define the chart using Altair
chart = alt.Chart(chartdf).mark_bar().encode(
x=alt.X('Procente ramase de consumat:O', scale=x_scale),
y='Procente',
color=alt.condition(
alt.datum.results > alt.datum.max_values,
alt.value('red'), # Set the color to red if the result is greater than the max value
alt.value('blue'), # Set the color to blue if the result is less than or equal to the max value
)
).properties(
width=alt.Step(40), # Set the width of each bar
)
# Display the chart in Streamlit
st.altair_chart(chart, use_container_width=True)
#sidebar for categories
# Define columns to display and exclude
all_columns = new_index
df.iloc[0, 2:] = new_index
# set the column names to the values in the first row
df = df.iloc[1:]
# concatenate the original column index sliced from the third column onward with the new column index
new_col_index = df.columns[:2].tolist() + new_index
# set the new column index
df.set_axis(new_col_index, axis=1, inplace=True)
df = df.set_index(0)
df.iloc[1:, 2:] = df.iloc[1:, 2:].astype(float)
st.write('Sorteaza coloanele dupa valorile ramase pentru a gasi ingrediente ce pot acoperi diferentele, valorile sunt pentru 100 de grame')
st.dataframe(df.iloc[:, 1:].astype(float), height=400)
df1.replace(r'^\s*$', np.nan, regex=True, inplace=True) # replace empty white spaces with NaN
df1.dropna(how='all', inplace=True) # drop empty rows
df1 = df1.reset_index(drop=True) # reset the index to remove null values
df1.dropna(subset=[df1.columns[0]], inplace=True) # drop any rows with null values in the first column
df1 = df1.set_index(df1.columns[0]) # set the index to the first column
df1 = df1.drop([1, 2, 5, 6], axis=1) # drop some columns
df1.columns = ['Ingrediente', 'Gramaj'] # rename columns
st.write('Cauta reteta dupa ingredient, deschide bara laterala, adauga reteta, selecteaza gramajul si descopera valorile nutritive')
col1, col2, col3 = st.columns((1, 4, 1))
# Use the middle column for displaying the dataframe
with col2:
st.dataframe(df1, height=400)
st.sidebar.markdown("---")
st.sidebar.write("Pentru a ajunge in magazin puteti da click pe banner-ul Gradina Slavu! Multumim!")
st.sidebar.markdown("---")
df=pd.DataFrame(rows)
lista=list(df[0])
#selectare ingredient