middleschool / Middle_School_Card_Search.py
Alejandro Cremades
Filter cards by power and toughness ranges
fd1f4c2
raw
history blame
6.3 kB
import streamlit as st
import pandas as pd
import streamlit_common.footer
import streamlit_common.lib as lib
import streamlit_common.locale
mslist_path = "output/middleschool_extra_fields.csv"
_ = streamlit_common.locale.get_locale()
if "number_shown_results" not in st.session_state:
st.session_state["number_shown_results"] = 20
if "lang" not in st.session_state:
st.session_state["lang"] = "en"
def add_more_results():
st.session_state["number_shown_results"] += 20
def reset_more_results():
st.session_state["number_shown_results"] = 20
st.set_page_config(
page_title="Middle School Tutor | Card Search",
page_icon="favicon.ico",
layout="wide",
)
lang = st.sidebar.radio(
label="Language / 言語",
options=["English", "日本語"],
index=1 if st.session_state["lang"] == "ja" else 0,
)
st.session_state["lang"] = "ja" if lang == "日本語" else "en"
l = st.session_state["lang"]
headcol1, headcol2 = st.columns([1, 7])
headcol1.image("favicon.ico", width=80)
headcol2.write(f"# Middle School Tutor")
st.write(f'## {_["search"]["title"][l]}')
st.write(_["search"]["instructions"][l])
mslist_df = pd.read_csv(mslist_path)
mslist_df.fillna("", inplace=True)
st.write(f'**{mslist_df.shape[0]}**{_["search"]["cards_are_legal"][l]}')
results_df = mslist_df
# Filter by card name
input_name = st.text_input(
f'**{_["search"]["search_by_card_name"][l]}**',
placeholder=_["search"]["search_by_card_name_placeholder"][l],
).strip()
exact_match = lib.get_legal_cardnames(input_name, mslist_df)
results_en_df = results_df[results_df["name"].str.contains(input_name, case=False)]
results_ja_df = results_df[results_df["name_ja"].str.contains(input_name, case=False)]
results_df = results_en_df.merge(results_ja_df, how="outer")
# Filter by color
(
colorcol0,
colorcol1,
colorcol2,
colorcol3,
colorcol4,
colorcol5,
colorcol6,
) = st.columns(7)
colorcol0.write(f'**{_["search"]["search_by_color"][l]}**')
if colorcol1.checkbox(_["basic"]["color_w"][l]):
results_df = results_df[results_df["w"] == True]
if colorcol2.checkbox(_["basic"]["color_u"][l]):
results_df = results_df[results_df["u"] == True]
if colorcol3.checkbox(_["basic"]["color_b"][l]):
results_df = results_df[results_df["b"] == True]
if colorcol4.checkbox(_["basic"]["color_r"][l]):
results_df = results_df[results_df["r"] == True]
if colorcol5.checkbox(_["basic"]["color_g"][l]):
results_df = results_df[results_df["g"] == True]
if colorcol6.checkbox(_["basic"]["color_c"][l]):
results_df = results_df[results_df["c"] == True]
# Filter by mana value range
min_mv = mslist_df["mv"].min()
max_mv = mslist_df["mv"].max()
mv_options = [mv for mv in range(min_mv, max_mv + 1)]
start_mv, end_mv = st.select_slider(
f'**{_["search"]["search_by_mv"][l]}**', options=mv_options, value=(min_mv, max_mv)
)
cond1 = results_df["mv"] >= start_mv
cond2 = results_df["mv"] <= end_mv
results_df = results_df[cond1 & cond2]
# Filter by type (select)
col1, col2 = st.columns(2)
type_list = streamlit_common.locale.get_type_options()
select_types = col1.multiselect(
f'**{_["search"]["select_type"][l]}**',
type_list[l],
placeholder=_["search"]["select_type_placeholder"][l],
)
for cardtype in select_types:
type_to_search = cardtype
if l == "ja":
type_to_search = type_list["en"][type_list["ja"].index(cardtype)]
results_df = results_df[results_df["type"].str.contains(type_to_search, case=False)]
# Filter by type (text input)
input_type = col2.text_input(
f'**{_["search"]["search_by_type"][l]}**',
placeholder=_["search"]["search_by_type_placeholder"][l],
).strip()
results_df = results_df[results_df["type"].str.contains(input_type, case=False)]
# Filter by text
input_text = st.text_input(
f'**{_["search"]["search_by_text"][l]}**',
placeholder=_["search"]["search_by_text_placeholder"][l],
).strip()
results_df = results_df[results_df["text"].str.contains(input_text, case=False)]
# Filter by power and toughness ranges
powtou_df = mslist_df[mslist_df["power"].isin(range(0, 100))]
min_pow = int(powtou_df["power"].min(skipna=True))
max_pow = int(powtou_df["power"].max(skipna=True))
pow_range = range(min_pow, max_pow + 1)
pow_options = [pow for pow in pow_range]
start_pow, end_pow = st.select_slider(
f'**{_["search"]["search_by_pow"][l]}**',
options=pow_options,
value=(min_pow, max_pow),
)
if start_pow > min_pow or end_pow < max_pow:
results_df = results_df[results_df["power"].isin(pow_range)]
results_df = results_df[results_df["power"] >= start_pow]
results_df = results_df[results_df["power"] <= end_pow]
min_tou = int(powtou_df["toughness"].min(skipna=True))
max_tou = int(powtou_df["toughness"].max(skipna=True))
tou_range = range(min_tou, max_tou + 1)
tou_options = [tou for tou in tou_range]
start_tou, end_tou = st.select_slider(
f'**{_["search"]["search_by_tou"][l]}**',
options=tou_options,
value=(min_tou, max_tou),
)
if start_tou > min_tou or end_tou < max_tou:
results_df = results_df[results_df["toughness"].isin(tou_range)]
results_df = results_df[results_df["toughness"] >= start_tou]
results_df = results_df[results_df["toughness"] <= end_tou]
if results_df.shape[0] < mslist_df.shape[0]:
if exact_match[0]:
cardname = exact_match[1]
if exact_match[2] is not None:
cardname = f"{cardname} / {exact_match[2]}"
st.write(
f'✅ [{cardname}]({lib.compose_scryfall_url(exact_match[1])}) {_["search"]["exact_match"][l]}'
)
st.write(f'**{results_df.shape[0]}**{_["search"]["cards_found"][l]}')
if results_df.shape[0] > st.session_state["number_shown_results"]:
st.write(_["search"]["top_results"][l])
results_df["link"] = results_df["name"].apply(lib.compose_scryfall_url)
results_df[: st.session_state["number_shown_results"]].transpose().apply(
lib.row_to_link
)
if results_df.shape[0] > st.session_state["number_shown_results"]:
st.button(label=_["search"]["see_more"][l], on_click=add_more_results)
if st.session_state["number_shown_results"] > 20:
st.button(
label=_["search"]["see_20"][l],
on_click=reset_more_results,
)
streamlit_common.footer.write_footer()