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"""
""", 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('Nu uita sa deselectezi optiunile din sidebar, in cazul in care meniul nu se afiseaza!', 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'{url}' 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