File size: 4,258 Bytes
a9d9e97
 
705057b
e988e3b
c4dea99
 
e988e3b
705057b
e2531ec
eb1ab19
e988e3b
e2531ec
 
c3096f2
46d4747
 
 
 
dbb4724
 
 
db82ba3
 
 
 
8ff835f
 
 
 
 
 
 
 
 
 
dbb4724
 
 
 
 
 
 
 
 
8ff835f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e48f638
06a63d9
db82ba3
06a63d9
5e99366
 
 
 
 
 
 
 
06a63d9
dbb4724
 
db82ba3
dbb4724
8ff835f
46d4747
8ff835f
db82ba3
06a63d9
5e99366
dbb4724
db46464
1a8aed3
e48f638
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import pandas as pd
import streamlit as st
import json

st.set_page_config(layout="wide")

# load data
f = open('data.json')
recipes_json = json.load(f)

# prepare data
recipes = pd.DataFrame(recipes_json)
ingredients = pd.DataFrame(recipes_json).explode('ingredients')

def get_bar_data():
    bar_dict = [{"ingredients":"rye", "have": False}, {"ingredients":"cognac", "have": False}]
    return pd.DataFrame(bar_dict)

if 'filter_bar' not in st.session_state:
    st.session_state.filter_bar = recipes['name'].to_list()

if 'bar_df' not in st.session_state:
    st.session_state.bar_df = get_bar_data()
    st.session_state.bar_df_edited = st.session_state.bar_df.copy() 

with st.expander("Search and filter recipes"):
    # name search
    name_search = st.text_input('Search recipes by name')
    if name_search == "":
        filter_name = recipes['name'].to_list()
    else:
        filter_1 = recipes['name'].str.contains(name_search)
        filter_name = recipes.loc[filter_1, 'name'].to_list()
    
    # ingredient filter
    options = st.multiselect(
        'Select ingredients to filter by:',ingredients['ingredients'].unique())
    filter_type = st.radio(
        "Specify type of ingredient filtering:",
        [
            'Recipe contains ANY of the specified ingredients', 
            'Recipe contains ALL of the specified ingredients'
        ]
    )
    if len(options)==0:
        filter_ingredient = recipes['name'].to_list()
    else:
        if filter_type == 'Recipe contains ANY of the specified ingredients':
            filter_1 = ingredients['ingredients'].isin(options)
            filter_ingredient = ingredients.loc[filter_1, 'name'].to_list()
        elif filter_type == 'Recipe contains ALL of the specified ingredients':
            filter_1 = ingredients['ingredients'].isin(options)
            ingredients['has_ingredient'] = 0
            ingredients.loc[filter_1, 'has_ingredient'] = 1
            pivot = ingredients.groupby('name').agg(sum_has_ingredients=('has_ingredient', 'sum')).reset_index()
            filter_ingredient = pivot.loc[pivot['sum_has_ingredients']==len(options), 'name'].to_list()
    
    # source filter
    source_options = st.multiselect(
        'Filter by source:',recipes['source'].unique())      
    if len(source_options)==0:
        filter_source = recipes['name'].to_list()
    else:
        filter_1 = recipes['source'].isin(source_options)
        filter_source = recipes.loc[filter_1, 'name'].to_list()
    
    # type filter
    type_options = st.multiselect(
        'Filter by type:',recipes['recipe_type'].unique())      
    if len(type_options)==0:
        filter_type = recipes['name'].to_list()
    else:
        filter_1 = recipes['recipe_type'].isin(type_options)
        filter_type = recipes.loc[filter_1, 'name'].to_list()

def submit_bar():
    ingredients_joined = ingredients.join(st.session_state.bar_df_edited.set_index('ingredients'), on='ingredients')
    ingredients_joined.replace({'have': {True: 1, False: 0}}, inplace=True)
    if bar_df_edited['have'].sum() == 0:
        st.session_state.filter_bar = recipes['name'].to_list()
    else:
        pivot = ingredients_joined.groupby('name').agg(sum_needs_ingredients=('have', 'count'), sum_has_ingredients=('have', 'sum')).reset_index()
        filter_1 = (pivot['sum_has_ingredients'] > 0) & (pivot['sum_needs_ingredients'] > 0)
        filter_2 = pivot['sum_needs_ingredients'] == pivot['sum_has_ingredients']
        filter_all = filter_1 & filter_2
        st.session_state.filter_bar = pivot.loc[filter_all, 'name'].to_list()

def reset_bar():
    st.session_state.filter_bar = recipes['name'].to_list()
    st.session_state.bar_df_edited = get_bar_data()

with st.expander("Home bar"):
    bar_df = get_bar_data()
    # input home bar
    st.session_state.bar_df_edited = st.data_editor(st.session_state.bar_df, disabled=["ingredients"], hide_index=True)
    st.button(label='Submit Bar', on_click=submit_bar)
    st.button(label='Reset', on_click=reset_bar)
        
st.header("Recipes")
filter_all = list(set(filter_name) & set(filter_ingredient) & set(filter_source) & set(filter_type) & set(st.session_state.filter_bar))
st.dataframe(recipes[recipes['name'].isin(filter_all)], hide_index=True)