Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| st.set_page_config(layout="wide") | |
| css = """ | |
| <style> | |
| /* Remove extra spacing in markdown paragraphs */ | |
| .stMarkdown p { | |
| margin: 0 !important; | |
| padding: 0 !important; | |
| } | |
| /* Compact styling for criterion name and description */ | |
| .criteria-name { | |
| font-size: 12px; | |
| font-weight: bold; | |
| } | |
| .criteria-description { | |
| font-size: 10px; | |
| color: #555; | |
| } | |
| .category-header { | |
| margin-top: 6px; | |
| margin-bottom: 3px; | |
| font-size: 14px; | |
| font-weight: bold; | |
| border-bottom: 1px solid #ccc; | |
| padding-bottom: 2px; | |
| } | |
| .app-header { | |
| text-align: center; | |
| margin-bottom: 6px; | |
| font-size: 20px; | |
| } | |
| /* Enlarge slider thumb for easier touch */ | |
| div[data-baseweb="slider"] .Thumb { | |
| width: 36px !important; | |
| height: 36px !important; | |
| } | |
| /* Hide slider tick marks, tick bar, min/max texts, and empty slider label */ | |
| div[data-baseweb="slider"] .Tick, | |
| div[data-baseweb="slider"] .TickBar, | |
| div[data-testid="stSliderTickBarMin"], | |
| div[data-testid="stSliderTickBarMax"], | |
| div[data-testid="stSliderThumbValue"], | |
| label[data-testid="stWidgetLabel"][aria-hidden="true"] { | |
| display: none !important; | |
| } | |
| .stSlider { | |
| margin-top: -10px !important; | |
| } | |
| /* Mobile adjustments */ | |
| @media (max-width: 600px) { | |
| .stHorizontalBlock { | |
| flex-wrap: nowrap !important; | |
| } | |
| .stColumn { | |
| padding-left: 2px !important; | |
| padding-right: 2px !important; | |
| min-width: 0; | |
| } | |
| .stCheckbox { | |
| transform: scale(0.8); | |
| transform-origin: left center; | |
| } | |
| } | |
| </style> | |
| """ | |
| st.markdown(css, unsafe_allow_html=True) | |
| criteria = { | |
| "Writing": [ | |
| {"name": "Dialogue", "description": "Word choice, realism, subtext, and implications."}, | |
| {"name": "Screenwriting", "description": "Structure, plot progression, and narrative choices."}, | |
| {"name": "Character Development", "description": "Depth, relatability, motivations, and arcs."}, | |
| {"name": "Theme & Symbolism", "description": "Use of deeper meaning, metaphors, and thematic consistency."} | |
| ], | |
| "Cinematography": [ | |
| {"name": "Camera Work", "description": "Shot composition, stability, movement, and angles."}, | |
| {"name": "Lighting", "description": "Contrast, exposure control, and mood-setting."}, | |
| {"name": "Color Grading", "description": "Palette consistency, contrast, and emotional tone."}, | |
| {"name": "Framing & Aspect Ratio", "description": "Use of space, focus, and visual storytelling."} | |
| ], | |
| "Editing & Pacing": [ | |
| {"name": "Scene Transitions", "description": "Smoothness, creativity, and effectiveness."}, | |
| {"name": "Continuity", "description": "Logical flow and lack of visual inconsistencies."}, | |
| {"name": "Pacing", "description": "Balance between slow and fast scenes, engagement level."}, | |
| {"name": "Use of Montage", "description": "Storytelling efficiency via edited sequences."} | |
| ], | |
| "Sound": [ | |
| {"name": "Dialogue Mixing", "description": "Clarity, balance, and intelligibility of speech."}, | |
| {"name": "Foley & Sound Effects", "description": "Realism, accuracy, and integration into the world."}, | |
| {"name": "Score & Music", "description": "Uniqueness, memorability, and emotional impact."}, | |
| {"name": "Spatial Audio & Atmosphere", "description": "Immersion, ambient sound accuracy, and use of silence."} | |
| ], | |
| "Directing & Performance": [ | |
| {"name": "Directing", "description": "Cohesion of vision, creative choices, and execution."}, | |
| {"name": "Acting", "description": "Expression, dialogue delivery, and emotional depth."}, | |
| {"name": "Blocking & Staging", "description": "Character positioning, movement, and scene composition."}, | |
| {"name": "Action & Stunt Choreography", "description": "Realism, execution, and visual readability."} | |
| ], | |
| "Production & Visuals": [ | |
| {"name": "Production Design", "description": "Set design, world-building, and authenticity."}, | |
| {"name": "Costume & Makeup", "description": "Period accuracy, character enhancement, and detailing."}, | |
| {"name": "Practical Effects & Props", "description": "Use of real elements over CGI, believability."}, | |
| {"name": "VFX & CGI Integration", "description": "Quality, realism, and seamless blending."} | |
| ], | |
| "Engagement & Replay Value": [ | |
| {"name": "Plot", "description": "Uniqueness, engagement, predictability, and emotional weight."}, | |
| {"name": "Originality", "description": "Avoidance of clichés, fresh storytelling, and innovation."}, | |
| {"name": "Rewatchability", "description": "Whether the movie holds up over multiple viewings."}, | |
| {"name": "Emotional Impact", "description": "Strength of connection, intensity of response."} | |
| ] | |
| } | |
| def calculate_score(ratings): | |
| valid = [r for r in ratings if r is not None] | |
| if not valid: | |
| return "Please rate at least one criterion." | |
| avg = sum(valid) / len(valid) | |
| scaled_score = (1/18) * (avg ** 2) + (19/18) * avg - (1/9) | |
| return f"Final Scaled Score: {scaled_score:.2f} / 10" | |
| st.markdown("<h1 class='app-header'>Movie Rating System</h1>", unsafe_allow_html=True) | |
| ratings = [] | |
| # For each criterion, display a row with the checkbox on the left, then title/description and slider | |
| for group, subcriteria in criteria.items(): | |
| st.markdown(f"<div class='category-header'>{group}</div>", unsafe_allow_html=True) | |
| for idx, crit in enumerate(subcriteria): | |
| with st.container(): | |
| cols = st.columns([0.5, 7]) | |
| checkbox_col = cols[0] | |
| combined_col = cols[1] | |
| include = checkbox_col.checkbox("", value=True, key=f"include_{group}_{idx}") | |
| combined = ( | |
| f"<span class='criteria-name'>{crit['name']}</span>" | |
| f" " | |
| f"<span class='criteria-description'>{crit['description']}</span>" | |
| ) | |
| combined_col.markdown(combined, unsafe_allow_html=True) | |
| rating = combined_col.slider( | |
| "", 1.0, 7.0, 4.0, step=0.01, key=f"slider_{group}_{idx}", disabled=(not include) | |
| ) | |
| ratings.append(None if not include else rating) | |
| if st.button("Calculate Score"): | |
| result = calculate_score(ratings) | |
| st.markdown(f"<h2 style='text-align:center;'>{result}</h2>", unsafe_allow_html=True) | |