ez326/Movie-Rating-Algorithm
0
1import streamlit as st
2
3st.set_page_config(layout="wide")
4
5css = """
6<style>
7 /* Remove extra spacing in markdown paragraphs */
8 .stMarkdown p {
9 margin: 0 !important;
10 padding: 0 !important;
11 }
12 /* Compact styling for criterion name and description */
13 .criteria-name {
14 font-size: 12px;
15 font-weight: bold;
16 }
17 .criteria-description {
18 font-size: 10px;
19 color: #555;
20 }
21 .category-header {
22 margin-top: 6px;
23 margin-bottom: 3px;
24 font-size: 14px;
25 font-weight: bold;
26 border-bottom: 1px solid #ccc;
27 padding-bottom: 2px;
28 }
29 .app-header {
30 text-align: center;
31 margin-bottom: 6px;
32 font-size: 20px;
33 }
34 /* Enlarge slider thumb for easier touch */
35 div[data-baseweb="slider"] .Thumb {
36 width: 36px !important;
37 height: 36px !important;
38 }
39 /* Hide slider tick marks, tick bar, min/max texts, and empty slider label */
40 div[data-baseweb="slider"] .Tick,
41 div[data-baseweb="slider"] .TickBar,
42 div[data-testid="stSliderTickBarMin"],
43 div[data-testid="stSliderTickBarMax"],
44 div[data-testid="stSliderThumbValue"],
45 label[data-testid="stWidgetLabel"][aria-hidden="true"] {
46 display: none !important;
47 }
48 .stSlider {
49 margin-top: -10px !important;
50 }
51 /* Mobile adjustments */
52 @media (max-width: 600px) {
53 .stHorizontalBlock {
54 flex-wrap: nowrap !important;
55 }
56 .stColumn {
57 padding-left: 2px !important;
58 padding-right: 2px !important;
59 min-width: 0;
60 }
61 .stCheckbox {
62 transform: scale(0.8);
63 transform-origin: left center;
64 }
65 }
66</style>
67"""
68st.markdown(css, unsafe_allow_html=True)
69
70criteria = {
71 "Writing": [
72 {"name": "Dialogue", "description": "Word choice, realism, subtext, and implications."},
73 {"name": "Screenwriting", "description": "Structure, plot progression, and narrative choices."},
74 {"name": "Character Development", "description": "Depth, relatability, motivations, and arcs."},
75 {"name": "Theme & Symbolism", "description": "Use of deeper meaning, metaphors, and thematic consistency."}
76 ],
77 "Cinematography": [
78 {"name": "Camera Work", "description": "Shot composition, stability, movement, and angles."},
79 {"name": "Lighting", "description": "Contrast, exposure control, and mood-setting."},
80 {"name": "Color Grading", "description": "Palette consistency, contrast, and emotional tone."},
81 {"name": "Framing & Aspect Ratio", "description": "Use of space, focus, and visual storytelling."}
82 ],
83 "Editing & Pacing": [
84 {"name": "Scene Transitions", "description": "Smoothness, creativity, and effectiveness."},
85 {"name": "Continuity", "description": "Logical flow and lack of visual inconsistencies."},
86 {"name": "Pacing", "description": "Balance between slow and fast scenes, engagement level."},
87 {"name": "Use of Montage", "description": "Storytelling efficiency via edited sequences."}
88 ],
89 "Sound": [
90 {"name": "Dialogue Mixing", "description": "Clarity, balance, and intelligibility of speech."},
91 {"name": "Foley & Sound Effects", "description": "Realism, accuracy, and integration into the world."},
92 {"name": "Score & Music", "description": "Uniqueness, memorability, and emotional impact."},
93 {"name": "Spatial Audio & Atmosphere", "description": "Immersion, ambient sound accuracy, and use of silence."}
94 ],
95 "Directing & Performance": [
96 {"name": "Directing", "description": "Cohesion of vision, creative choices, and execution."},
97 {"name": "Acting", "description": "Expression, dialogue delivery, and emotional depth."},
98 {"name": "Blocking & Staging", "description": "Character positioning, movement, and scene composition."},
99 {"name": "Action & Stunt Choreography", "description": "Realism, execution, and visual readability."}
100 ],
101 "Production & Visuals": [
102 {"name": "Production Design", "description": "Set design, world-building, and authenticity."},
103 {"name": "Costume & Makeup", "description": "Period accuracy, character enhancement, and detailing."},
104 {"name": "Practical Effects & Props", "description": "Use of real elements over CGI, believability."},
105 {"name": "VFX & CGI Integration", "description": "Quality, realism, and seamless blending."}
106 ],
107 "Engagement & Replay Value": [
108 {"name": "Plot", "description": "Uniqueness, engagement, predictability, and emotional weight."},
109 {"name": "Originality", "description": "Avoidance of clichés, fresh storytelling, and innovation."},
110 {"name": "Rewatchability", "description": "Whether the movie holds up over multiple viewings."},
111 {"name": "Emotional Impact", "description": "Strength of connection, intensity of response."}
112 ]
113}
114
115def calculate_score(ratings):
116 valid = [r for r in ratings if r is not None]
117 if not valid:
118 return "Please rate at least one criterion."
119 avg = sum(valid) / len(valid)
120 scaled_score = (1/18) * (avg ** 2) + (19/18) * avg - (1/9)
121 return f"Final Scaled Score: {scaled_score:.2f} / 10"
122
123st.markdown("<h1 class='app-header'>Movie Rating System</h1>", unsafe_allow_html=True)
124ratings = []
125
126# For each criterion, display a row with the checkbox on the left, then title/description and slider
127for group, subcriteria in criteria.items():
128 st.markdown(f"<div class='category-header'>{group}</div>", unsafe_allow_html=True)
129 for idx, crit in enumerate(subcriteria):
130 with st.container():
131 cols = st.columns([0.5, 7])
132 checkbox_col = cols[0]
133 combined_col = cols[1]
134 include = checkbox_col.checkbox("", value=True, key=f"include_{group}_{idx}")
135 combined = (
136 f"<span class='criteria-name'>{crit['name']}</span>"
137 f" "
138 f"<span class='criteria-description'>{crit['description']}</span>"
139 )
140 combined_col.markdown(combined, unsafe_allow_html=True)
141 rating = combined_col.slider(
142 "", 1.0, 7.0, 4.0, step=0.01, key=f"slider_{group}_{idx}", disabled=(not include)
143 )
144 ratings.append(None if not include else rating)
145
146if st.button("Calculate Score"):
147 result = calculate_score(ratings)
148 st.markdown(f"<h2 style='text-align:center;'>{result}</h2>", unsafe_allow_html=True)
149 