Skip to content

Instantly share code, notes, and snippets.

@truevis
Last active September 18, 2025 18:43
Show Gist options
  • Select an option

  • Save truevis/ea06511ed1c965d5cd85545efd4fa0bd to your computer and use it in GitHub Desktop.

Select an option

Save truevis/ea06511ed1c965d5cd85545efd4fa0bd to your computer and use it in GitHub Desktop.
Streamlit app that loads a CSV of window specs and lets users filter rows by keyword. Basically a searchable window catalog that saves you from endless Home Depot tabs.
import io
import pandas as pd
import streamlit as st
# Window CSV data
EMBEDDED_CSV = """"Manufacturer","Series/Model","Type","Material","Glazing/Insulation","U-Factor (typ)","SHGC (typ)","Common Size Range (in)","Typical Price (USD)","Notes"
"Andersen","100 Series","Single-Hung","Fibrex composite","Low-E dual-pane argon","0.28-0.30","0.19-0.30","24-48 W x 36-72 H","450-900","Budget composite line; ENERGY STAR options"
"Andersen","100 Series","Gliding","Fibrex composite","Low-E SmartSun option","0.27-0.29","0.19-0.28","36-72 W x 24-60 H","600-1,000","Retail sizes like 47.5x47.5 sold at Home Depot"
"Andersen","100 Series","Picture","Fibrex composite","Low-E dual-pane","0.27-0.29","0.20-0.30","24-72 W x 24-72 H","300-800","Fixed unit; high VT options"
"Andersen","400 Series","Double-Hung","Wood clad","Low-E dual-pane","~0.30","~0.19","24-48 W x 36-72 H","700-1,400","Classic wood-clad favorite"
"Andersen","A-Series","Double-Hung","Wood clad + fiberglass/Fibrex","Advanced Low-E options","0.24-0.28","0.18-0.30","up to ~48 W x 96 H","1,000-2,000","Best-performing DH in Andersen lineup"
"Pella","250 Series","Double-Hung","Vinyl","Multi-chamber frame","0.27-0.30","0.20-0.30","24-48 W x 36-72 H","350-850","Stronger-than-ordinary vinyl; online configurable"
"Pella","250 Series","Sliding","Vinyl","Low-E dual-pane","0.27-0.29","0.21-0.31","36-72 W x 24-60 H","350-900","Horizontal slider"
"Pella","250 Series","Picture","Vinyl","Low-E dual-pane","0.26-0.29","0.20-0.32","24-72 W x 24-72 H","250-650","Fixed; many stock sizes"
"Pella","250 Series","Single-Hung","Vinyl","Low-E dual-pane","0.27-0.30","0.20-0.30","24-48 W x 36-71.5 H","300-800","Available at Lowe’s with egress sizes"
"Pella","250 Series","Awning","Vinyl","Low-E dual-pane","0.27-0.29","0.21-0.31","24-48 W x 18-36 H","300-700","Top-hinged venting"
"Marvin","Elevate","Casement","Fiberglass ext/wood int","Low-E2/3 dual or triple","0.26-0.29","0.20-0.35","18-36 W x 24-72 H","900-1,600","Hybrid durability/performance"
"Marvin","Elevate","Double-Hung","Fiberglass ext/wood int","Low-E dual-pane","~0.29","0.20-0.35","24-48 W x 36-72 H","900-1,600","ENERGY STAR packages"
"Marvin","Essential","Glider","All fiberglass","Low-E dual-pane","0.25-0.35","0.20-0.40","up to ~72 W x 60 H (dual)","800-1,400","Consistent nominal sizing catalog"
"Marvin","Essential","Picture","All fiberglass","Low-E dual/triple","0.25-0.35","0.20-0.45","24-96 W x 24-72 H","500-1,200","Direct-glaze or in-sash"
"Marvin","Essential","Awning","All fiberglass","Low-E dual-pane","0.25-0.35","0.20-0.40","24-48 W x 18-42 H","700-1,200","Fiberglass strength; low maintenance"
"Milgard","V400 Tuscany","Single-Hung","Vinyl","SunCoat Low-E","~0.29","0.22-0.35","24-48 W x 36-72 H","300-700","Traditional profile; many colors"
"Milgard","V400 Tuscany","Horizontal Slider","Vinyl","SunCoat Low-E","~0.29","0.22-0.35","36-72 W x 24-60 H","350-800","Popular West Coast slider"
"Milgard","V400 Tuscany","Picture","Vinyl","SunCoat Low-E","~0.28","0.22-0.36","24-72 W x 24-72 H","250-650","Fixed lite"
"Milgard","V400 Tuscany","Double-Hung","Vinyl","SunCoat/3D packages","0.27-0.30","0.22-0.33","24-48 W x 36-72 H","400-850","Optional 3D® MAX energy package"
"Milgard","Quiet Line","Sound Control","Vinyl","Enhanced acoustic IGU","0.29-0.35","0.20-0.30","Custom","1,500-2,500","High STC soundproof series"
"JELD-WEN","V-4500","Sliding","Vinyl","Low-E dual-pane","~0.29","0.20-0.33","48-72 W x 36-60 H","600-900","Home Depot shows 59.5x47.5 around ~$670"
"JELD-WEN","V-4500","Picture","Vinyl","Low-E dual-pane","0.27-0.30","0.20-0.34","24-72 W x 24-72 H","250-650","Fixed unit"
"JELD-WEN","V-2500","Single-Hung","Vinyl","Low-E dual-pane","0.28-0.30","0.20-0.34","24-48 W x 36-72 H","250-600","Budget line; many stock sizes"
"JELD-WEN","V-2500","Sliding","Vinyl","Low-E dual-pane","0.28-0.31","0.20-0.34","48-96 W x 36-60 H","350-700","Lowe’s carries multiple sizes"
"Simonton","DaylightMax","Single-Hung","Vinyl","ProSolar Low-E + Argon","~0.26-0.28","~0.23","24-48 W x 36-72 H","400-900","Slim frame, more glass"
"Simonton","DaylightMax","Picture","Vinyl","ProSolar Low-E + Argon","~0.26-0.27","~0.23-0.30","24-72 W x 24-72 H","300-700","Fixed; ENERGY STAR options"
"Simonton","DaylightMax","Slider","Vinyl","ProSolar Low-E + Argon","~0.27-0.29","~0.23-0.33","36-72 W x 24-60 H","400-900","Title 24 capable"
"Simonton","Madeira (region)","Double-Hung","Vinyl","Low-E + Argon","0.27-0.30","0.23-0.35","24-48 W x 36-72 H","500-1,000","Cost range avg $385-$1,450 installed"
"Ply Gem","Select Series","Single-Hung","Vinyl","HP/HP2+ glass","0.28-0.31","0.22-0.34","35.5x59.5 common","250-560","Home Depot stock colors incl. black/white"
"Ply Gem","Classic Series","Single-Hung","Vinyl","HP glass","0.29-0.31","0.22-0.34","47.5x59.5 common","300-600","Value line; screen included"
"Ply Gem","Select Series","Horizontal Slider","Vinyl","HP2+ glass","0.29-0.31","0.22-0.34","47.5x47.5 common","355-900","Left/right-handed sliders"
"Ply Gem","DaylightMax (Simonton brand)","Casement","Vinyl","ProSolar Low-E + Argon","~0.26","~0.23","18-36 W x 24-72 H","600-1,100","Performance sheet shows 0.26-0.27 U-factors"
"Alside","Mezzo","Double-Hung","Vinyl","Foam-enhanced chambers","0.27-0.30","0.20-0.33","24-48 W x 36-72 H","250-550","Energy-efficient vinyl line"
"Alside","Mezzo","Slider","Vinyl","Low-E dual-pane","0.28-0.31","0.22-0.34","36-72 W x 24-60 H","300-600","Multi-chamber frames"
"Alside","Mezzo","Picture","Vinyl","Low-E dual-pane","0.27-0.30","0.22-0.34","24-72 W x 24-72 H","220-500","Fixed"
"Alside","Mezzo","Awning","Vinyl","Low-E dual-pane","0.27-0.30","0.21-0.33","24-48 W x 18-36 H","300-650","Regional availability varies"
"VELUX","Fixed Skylight (FS)","Skylight","Aluminum/wood","Low-E laminated IGU","~0.42-0.50","~0.25-0.45","Multiple codes (e.g., 21x45, 30x46)","300-700","Basic fixed roof window"
"VELUX","Manual Venting (VS)","Skylight","Aluminum/wood","Low-E laminated IGU","~0.42-0.50","~0.25-0.45","Common codes (e.g., 21x45)","500-1,100","Hand-crank venting skylight"
"VELUX","Electric/Solar Venting","Skylight","Aluminum/wood","Low-E laminated IGU","~0.42-0.50","~0.25-0.45","Multiple sizes","1,000-2,500","Automated venting + shades"
"VELUX","Sun Tunnel","Tubular skylight","Aluminum tube","Acrylic/poly dome","N/A","N/A","10-22 in dia","300-1,000 installed","DIY kits $300–$600 typical"
"PGT","WinGuard Single-Hung","Impact (vinyl)","Vinyl","Impact laminated IGU","~0.29-0.35","0.20-0.35","Up to ~53x83","900-1,550 impact","Florida impact standard"
"PGT","WinGuard Picture","Impact (aluminum)","Aluminum","Impact laminated IGU","~0.35-0.50","0.20-0.40","Varies","400-1,245","Impact fixed window"
"PGT","EnergyVue Double-Hung","Impact (vinyl)","Vinyl","Impact laminated IGU","~0.29-0.33","0.20-0.35","Varies","800-1,465","EnergyVue impact line"
"PGT","WinGuard Horizontal Slider","Impact (vinyl)","Vinyl","Impact laminated IGU","~0.30-0.35","0.20-0.35","Varies","900-1,700","Impact slider"
"Harvey","Classic","Double-Hung","Vinyl","Low-E dual-pane","~0.24-0.29","0.20-0.33","Up to ~42x77","587-1,200",".24 U-value promo; typical installs $500–$1,500"
"Harvey","Majestic","Double-Hung","Wood/wood-clad","Low-E IGU","0.27-0.30","0.20-0.33","Custom","950-3,000 installed","Premium wood series"
"Harvey","Classic","Slider","Vinyl","Low-E dual-pane","0.28-0.31","0.21-0.34","36-72 W x 24-60 H","500-1,200","DP50 options"
"Harvey","Picture","Vinyl","Low-E dual-pane","0.27-0.30","0.21-0.35","24-72 W x 24-72 H","350-800","Fixed",""
"Kolbe","Ultra Series","Casement","Wood clad aluminum","Low-E dual/triple","0.24-0.30","0.18-0.35","18-36 W x 24-72 H","1,000-2,000","Title 24/PHIUS options per literature"
"Kolbe","Ultra Series","Double-Hung","Wood clad aluminum","Low-E IGU","0.26-0.31","0.20-0.36","24-48 W x 36-72 H","1,000-2,200","Hurricane/impact options"
"Sierra Pacific","H3","Double-Hung","Alum-clad wood + vinyl core","Low-E dual/triple","0.25-0.32","0.20-0.40","29-58 W x 29-59 H","917-1,654 bids","Hybrid H3 Fusion Tech"
"Sierra Pacific","H3","Picture","Alum-clad wood + vinyl core","Low-E IGU","0.25-0.32","0.20-0.40","29x29 common","558-1,200 bids","Thick extruded cladding"
"YKK AP","YES 60 TU","Storefront","Aluminum thermally broken","1"" IG; thermal struts","U≈0.40-0.42","N/A","Field fabricated","Project priced","Commercial storefront framing"
"YKK AP","YES 45 XT","Storefront","Aluminum dual thermal","1"" IG; dual barrier","U≈0.40","N/A","Field fabricated","Project priced","Energy-saving storefront"
"Kawneer","Trifab 451T","Storefront","Aluminum thermally improved","1"" IG; argon","Overall U≤~0.47","N/A","Field fabricated","Project priced","Spec guide lists tested U limits"
"CRL-U.S. Aluminum","ArcticFront 45X","Storefront/Entry","Aluminum thermal","1"" IG/triple options","U≈0.37 to 0.19","N/A","System-based","Project priced","NFRC-rated low U possible"
"CRL-U.S. Aluminum","CW high-perf","Curtain wall","Aluminum thermal","Triple-glazed","U≈0.32 to 0.17","N/A","System-based","Project priced","High-performance curtain wall"
"Andersen","100 Series","Awning","Fibrex composite","Low-E dual-pane","0.27-0.29","0.21-0.31","24-48 W x 18-36 H","500-900","Composite awning unit"
"Pella","250 Series","Awning","Vinyl","Low-E dual-pane","0.27-0.29","0.21-0.31","24-48 W x 18-36 H","350-750","Venting awning"
"Marvin","Elevate","Picture","Fiberglass/wood","Low-E dual/triple","0.25-0.30","0.20-0.40","24-96 W x 24-72 H","800-1,400","Fixed hybrid unit"
"JELD-WEN","V-4500","Awning","Vinyl","Low-E dual-pane","0.28-0.31","0.21-0.34","24-48 W x 18-36 H","300-650","Awning option in V-4500 family"
"""
def load_embedded_data() -> pd.DataFrame:
"""Load the embedded CSV string into a dataframe."""
return pd.read_csv(io.StringIO(EMBEDDED_CSV))
def filter_by_keyword(df: pd.DataFrame, keyword: str) -> pd.DataFrame:
"""Return rows containing the keyword in any column (case-insensitive)"""
if not keyword:
return df
# Check each column for the keyword in lowercase, returning True/False per cell.
matches = df.apply(
lambda col: col.astype(str).str.lower().str.contains(
keyword.lower(),
na=False, # na=False: treat NaN/None values as False (don't match)
regex=False # regex=False: treat the pattern as literal text, not regex
)
)
# Keep rows where any column contains the keyword.
return df[matches.any(axis=1)]
def main() -> None:
st.title("CSV Display with Keyword Filter")
# Load the embedded CSV to keep this script self-contained.
data = load_embedded_data()
# Ask the user for a keyword; leave blank to show the entire dataset.
keyword = st.text_input("Keyword to filter by")
# Apply the keyword filter to the dataframe.
filtered = filter_by_keyword(data, keyword)
# Display the filtered dataframe and hide the index for clarity.
st.dataframe(filtered)
st.markdown("""Streamlit Documentation Reference:
https://docs.streamlit.io/develop/api-reference/data/st.dataframe
""")
if __name__ == "__main__":
main()
@truevis
Copy link
Author

truevis commented Sep 18, 2025

bash "streamlit run streamlit_csv_display_with_filter.py" to test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment