Maryam Ilka commited on
Commit
3e69f41
·
verified ·
1 Parent(s): 75f564c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +207 -133
app.py CHANGED
@@ -65,22 +65,17 @@ st.markdown("""
65
  width: 100% !important;
66
  }
67
 
68
- .rahyar-btn-secondary {
69
- background-color: white !important;
70
- color: #6a0dad !important;
71
- border: 2px solid #6a0dad !important;
72
- }
73
-
74
- .explanation-title {
75
- color: #6a0dad;
76
- font-weight: bold;
77
- margin-top: 20px;
78
  }
79
 
80
- .explanation-item {
81
- margin: 10px 0;
82
- padding-right: 15px;
83
- border-right: 3px solid #6a0dad;
84
  }
85
 
86
  .survey-section {
@@ -99,20 +94,6 @@ st.markdown("""
99
  display: inline-block;
100
  margin-left: 10px;
101
  }
102
- .rahyar-header {
103
- background-color: #6a0dad;
104
- padding: 15px;
105
- border-radius: 10px;
106
- color: white;
107
- margin-bottom: 20px;
108
- text-align: center;
109
- }
110
-
111
- .rahyar-logo {
112
- display: block;
113
- margin: 0 auto;
114
- text-align: center;
115
- }
116
  </style>
117
  """, unsafe_allow_html=True)
118
 
@@ -164,10 +145,9 @@ def show_explanation(exp_type):
164
  }
165
 
166
  if exp_type != "control":
167
- with st.expander("🔍 مشاهده توضیحات قیمت", expanded=False):
168
- st.markdown("<p class='explanation-title'>علت قیمت گذاری:</p>", unsafe_allow_html=True)
169
- for item in explanations.get(exp_type, []):
170
- st.markdown(f"<p class='explanation-item'>• {item}</p>", unsafe_allow_html=True)
171
 
172
  # ========== توابع مدیریت داده‌ها ==========
173
  def get_credentials():
@@ -209,9 +189,8 @@ def save_to_sheet(data):
209
  data.get("gender"),
210
  data.get("education"),
211
  data.get("ride_frequency"),
212
- data.get("fairness"),
213
- data.get("transparency"),
214
- data.get("satisfaction")
215
  ]
216
 
217
  worksheet.append_row(row_data)
@@ -222,6 +201,25 @@ def save_to_sheet(data):
222
  return False
223
 
224
  # ========== بخش‌های فرم ==========
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  def demographic_form():
226
  """فرم اطلاعات دموگرافیک"""
227
  with st.form("demographic"):
@@ -232,119 +230,195 @@ def demographic_form():
232
  ride_frequency = st.selectbox("دفعات استفاده از سرویس‌های اشتراک سفر در ماه",
233
  ["کمتر از 5 بار", "5-10 بار", "بیش از 10 بار"])
234
 
235
- if st.form_submit_button("ذخیره اطلاعات"):
236
- return {
237
  "age": age,
238
  "gender": gender,
239
  "education": education,
240
  "ride_frequency": ride_frequency
241
  }
242
- return None
 
243
 
244
- def fairness_questionnaire():
245
- """پرسشنامه ادراک انصاف"""
246
- st.header("📊 پرسشنامه ادراک انصاف قیمتی")
247
-
248
- st.markdown("**لطفاً با توجه به قیمت و توضیحات ارائه شده به سوالات زیر پاسخ دهید:**")
 
 
 
 
 
 
249
 
250
- fairness = st.slider("به نظر شما این قیمت چقدر منصفانه است؟ (1 کاملاً ناعادلانه - 7 کاملاً عادلانه)", 1, 7)
251
- transparency = st.slider("چقدر توضیحات ارائه شده در مورد قیمت را شفاف می‌دانید؟ (1 کاملاً نامشخص - 7 کاملاً شفاف)", 1, 7)
252
- satisfaction = st.slider("چقدر از این قیمت‌گذاری راضی هستید؟ (1 کاملاً ناراضی - 7 کاملاً راضی)", 1, 7)
253
 
254
- return {
255
- "fairness": fairness,
256
- "transparency": transparency,
257
- "satisfaction": satisfaction
258
- }
259
-
260
- # ========== رابط کاربری اصلی ==========
261
- def main():
262
- # مدیریت وضعیت
263
- if 'scenario_type' not in st.session_state:
264
- st.session_state.scenario_type = random.choice(["control", "input", "counterfactual"])
265
- if 'price' not in st.session_state:
266
- st.session_state.price = 200000 # قیمت ثابت 200 هزار تومان
267
- if 'demographic_data' not in st.session_state:
268
- st.session_state.demographic_data = None
269
- if 'survey_completed' not in st.session_state:
270
- st.session_state.survey_completed = False
271
-
272
- # نمایش لوگو و هدر
273
- col1, col2 = st.columns([1, 3])
274
- with col1:
275
- st.image("rahyar.png", width=150) # عرض لوگو را تنظیم کنید
276
- with col2:
277
  st.markdown("""
278
- <div class="rahyar-header">
279
- <h2>راهیار 🚖</h2>
280
- <p>سفرهای درون شهری سریع و مطمئن</p>
281
  </div>
282
  """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
- # اگر اطلاعات دموگرافیک تکمیل نشده
285
- if not st.session_state.demographic_data:
286
- data = demographic_form()
287
- if data:
288
- st.session_state.demographic_data = data
289
- st.rerun()
290
- return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
- # اگر پرسشنامه تکمیل نشده
293
- if not st.session_state.survey_completed:
294
- # نمایش سناریو
295
- st.markdown("### مسیر سفر شما")
296
- folium_static(create_ride_map(), width=800, height=400)
297
-
298
- # نمایش قیمت و دکمه‌ها
299
- col1, col2 = st.columns([3, 2])
300
- with col1:
301
- st.markdown(f"""
302
- <div class="price-container">
303
- <div style="display: flex; justify-content: space-between; align-items: center;">
304
- <span>راهیار <span class="rahyar-badge">به صرفه</span></span>
305
- <span class="rahyar-price">{st.session_state.price:,} تومان</span>
306
- </div>
307
- </div>
308
- """, unsafe_allow_html=True)
309
-
310
- if st.session_state.scenario_type != "control":
311
- show_explanation(st.session_state.scenario_type)
312
-
313
- with col2:
314
- st.markdown("<br>", unsafe_allow_html=True)
315
- if st.button("درخواست رهیار", key="request_btn", type="primary"):
316
  pass
317
-
318
- if st.session_state.scenario_type != "control":
319
- if st.button("مشاهده توضیحات", key="explanation_btn",
320
- help="توضیحات قیمت گذاری این سفر"):
321
- pass
322
-
323
- # پرسشنامه
324
- with st.container():
325
- st.markdown("<div class='survey-section'>", unsafe_allow_html=True)
326
- survey_data = fairness_questionnaire()
327
- st.markdown("</div>", unsafe_allow_html=True)
328
-
329
- if st.button("ارسال پاسخ‌ها", type="primary"):
330
- all_data = {
331
- "scenario_type": st.session_state.scenario_type,
332
- "price": st.session_state.price,
333
- **st.session_state.demographic_data,
334
- **survey_data
335
- }
336
-
337
- if save_to_sheet(all_data):
338
- st.session_state.survey_completed = True
339
- st.rerun()
340
- else:
341
- # صفحه تشکر
342
- st.success("✅ پاسخ‌های شما با موفقیت ثبت شد. با تشکر از مشارکت شما در این تحقیق!")
343
- st.balloons()
344
-
345
- if st.button("بازگشت به ابتدا"):
346
- st.session_state.clear()
347
  st.rerun()
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  if __name__ == "__main__":
350
  main()
 
65
  width: 100% !important;
66
  }
67
 
68
+ .likert-btn {
69
+ margin: 5px;
70
+ padding: 10px 15px;
71
+ border-radius: 8px;
72
+ border: 1px solid #ddd;
73
+ background-color: white;
 
 
 
 
74
  }
75
 
76
+ .likert-btn-selected {
77
+ border: 2px solid #6a0dad !important;
78
+ background-color: #f0e6ff !important;
 
79
  }
80
 
81
  .survey-section {
 
94
  display: inline-block;
95
  margin-left: 10px;
96
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  </style>
98
  """, unsafe_allow_html=True)
99
 
 
145
  }
146
 
147
  if exp_type != "control":
148
+ st.markdown("<p style='color: #6a0dad; font-weight: bold; margin-top: 20px;'>علت قیمت گذاری:</p>", unsafe_allow_html=True)
149
+ for item in explanations.get(exp_type, []):
150
+ st.markdown(f"<p style='margin: 10px 0; padding-right: 15px; border-right: 3px solid #6a0dad;'>• {item}</p>", unsafe_allow_html=True)
 
151
 
152
  # ========== توابع مدیریت داده‌ها ==========
153
  def get_credentials():
 
189
  data.get("gender"),
190
  data.get("education"),
191
  data.get("ride_frequency"),
192
+ *data.get("transparency_answers", []),
193
+ *data.get("fairness_answers", [])
 
194
  ]
195
 
196
  worksheet.append_row(row_data)
 
201
  return False
202
 
203
  # ========== بخش‌های فرم ==========
204
+ def welcome_page():
205
+ """صفحه خوشامدگویی"""
206
+ st.markdown("""
207
+ <div style="text-align: center; margin-bottom: 30px;">
208
+ <h2>تحلیل انصاف قیمتی در پلتفرم‌های اشتراک سفر</h2>
209
+ <p>این تحقیق به بررسی تأثیر توضیحات قیمت بر ادراک انصاف می‌پردازد</p>
210
+ </div>
211
+
212
+ <div style="background-color: #f0f2f6; border-radius: 10px; padding: 20px;">
213
+ <h3>درباره تحقیق:</h3>
214
+ <p>این پرسشنامه بخشی از یک پژوهش علمی است که به بررسی ادراک انصاف در قیمت‌گذاری پویا می‌پردازد.</p>
215
+ <p>پس از مشاهده سناریو، لطفاً به سوالات پاسخ دهید.</p>
216
+ </div>
217
+ """, unsafe_allow_html=True)
218
+
219
+ if st.button("شروع پرسشنامه", key="start_btn", type="primary"):
220
+ st.session_state.current_page = "demographic"
221
+ st.rerun()
222
+
223
  def demographic_form():
224
  """فرم اطلاعات دموگرافیک"""
225
  with st.form("demographic"):
 
230
  ride_frequency = st.selectbox("دفعات استفاده از سرویس‌های اشتراک سفر در ماه",
231
  ["کمتر از 5 بار", "5-10 بار", "بیش از 10 بار"])
232
 
233
+ if st.form_submit_button("ادامه"):
234
+ st.session_state.demographic_data = {
235
  "age": age,
236
  "gender": gender,
237
  "education": education,
238
  "ride_frequency": ride_frequency
239
  }
240
+ st.session_state.current_page = "scenario_explanation"
241
+ st.rerun()
242
 
243
+ def scenario_explanation():
244
+ """توضیح سناریو"""
245
+ st.markdown("""
246
+ <div style="display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 20px;">
247
+ <img src="https://via.placeholder.com/100/6a0dad/FFFFFF?text=راهیار" width="80">
248
+ <div>
249
+ <h2 style="color: #6a0dad; margin: 0;">راهیار 🚖</h2>
250
+ <p style="color: #6a0dad; margin: 0;">سفرهای درون شهری سریع و مطمئن</p>
251
+ </div>
252
+ </div>
253
+ """, unsafe_allow_html=True)
254
 
255
+ st.markdown("### سناریوی تحقیق")
 
 
256
 
257
+ if st.session_state.scenario_type == "control":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  st.markdown("""
259
+ <div style="background-color: #f8f9fa; padding: 15px; border-radius: 10px;">
260
+ <p>شما قصد دارید سفری را از مبدأ میدان ونک به مقصد میدان تجریش درخواست کنید.</p>
261
+ <p>قیمت پیشنهادی این سفر 200,000 تومان است.</p>
262
  </div>
263
  """, unsafe_allow_html=True)
264
+ else:
265
+ st.markdown("""
266
+ <div style="background-color: #f8f9fa; padding: 15px; border-radius: 10px;">
267
+ <p>شما قصد دارید سفری را از مبدأ میدان ونک به مقصد میدان تجریش درخواست کنید.</p>
268
+ <p>قیمت پیشنهادی این سفر 200,000 تومان است.</p>
269
+ <p>پلتفرم توضیحاتی درباره علت این قیمت ارائه می‌دهد.</p>
270
+ </div>
271
+ """, unsafe_allow_html=True)
272
+
273
+ if st.button("ادامه", key="continue_btn", type="primary"):
274
+ st.session_state.current_page = "map_view"
275
+ st.rerun()
276
 
277
+ def map_view():
278
+ """نمایش نقشه و قیمت"""
279
+ st.markdown("""
280
+ <div style="display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 20px;">
281
+ <img src="https://via.placeholder.com/100/6a0dad/FFFFFF?text=راهیار" width="80">
282
+ <div>
283
+ <h2 style="color: #6a0dad; margin: 0;">راهیار 🚖</h2>
284
+ <p style="color: #6a0dad; margin: 0;">سفرهای درون شهری سریع و مطمئن</p>
285
+ </div>
286
+ </div>
287
+ """, unsafe_allow_html=True)
288
+
289
+ st.markdown("### مسیر سفر شما")
290
+ folium_static(create_ride_map(), width=800, height=400)
291
+
292
+ st.markdown(f"""
293
+ <div class="price-container">
294
+ <div style="display: flex; justify-content: space-between; align-items: center;">
295
+ <span>راهیار <span class="rahyar-badge">به صرفه</span></span>
296
+ <span class="rahyar-price">{st.session_state.price:,} تومان</span>
297
+ </div>
298
+ </div>
299
+ """, unsafe_allow_html=True)
300
+
301
+ show_explanation(st.session_state.scenario_type)
302
+
303
+ if st.button("درخواست راهیار", key="request_btn", type="primary"):
304
+ st.session_state.current_page = "transparency_questions"
305
+ st.rerun()
306
 
307
+ def create_likert_question(question, key):
308
+ """سوال لیکرت با دکمه‌ها"""
309
+ st.markdown(f"<p style='margin-bottom: 10px;'>{question}</p>", unsafe_allow_html=True)
310
+
311
+ cols = st.columns(5)
312
+ options = {
313
+ 1: "کاملاً مخالفم",
314
+ 2: "مخالفم",
315
+ 3: "نظری ندارم",
316
+ 4: "موافقم",
317
+ 5: "کاملاً موافقم"
318
+ }
319
+
320
+ selected = st.session_state.get(key, None)
321
+
322
+ for value, label in options.items():
323
+ with cols[value-1]:
324
+ if st.button(
325
+ label,
326
+ key=f"{key}_{value}",
327
+ on_click=lambda v=value: st.session_state.update({key: v}),
328
+ type="primary" if selected == value else "secondary"
329
+ ):
 
330
  pass
331
+
332
+ if selected:
333
+ st.markdown(f"<p style='color: #6a0dad;'>پاسخ شما: {options[selected]}</p>", unsafe_allow_html=True)
334
+
335
+ return selected
336
+
337
+ def transparency_questions():
338
+ """سوالات شفافیت"""
339
+ st.header("📊 پرسشنامه شفافیت قیمت")
340
+ st.markdown("**لطفاً میزان موافقت خود با جملات زیر را مشخص کنید:**")
341
+
342
+ questions = [
343
+ "پلتفرم به صورت صادقانه دلایل تغییر قیمت (مثل افزایش تقاضا یا شرایط جوی) را توضیح داد.",
344
+ "پلتفرم به طور کامل عوامل مؤثر بر قیمت (مثل ترافیک، تعداد رانندگان) را شرح داد.",
345
+ "دلایل ارائه‌شده برای تغییر قیمت منطقی و قابل قبول بود.",
346
+ "توضیحات درباره قیمت بلافاصله و در زمان مناسب نمایش داده شد.",
347
+ "توضیحات پلتفرم متناسب با شرایط سفر من (مثل مسیر یا ساعت درخواست) بود."
348
+ ]
349
+
350
+ answers = []
351
+ for i, question in enumerate(questions):
352
+ answer = create_likert_question(question, f"transparency_q{i}")
353
+ answers.append(answer)
354
+
355
+ if None not in answers:
356
+ st.session_state.transparency_answers = answers
357
+ if st.button("ادامه به سوالات بعدی", type="primary"):
358
+ st.session_state.current_page = "fairness_questions"
 
 
359
  st.rerun()
360
 
361
+ def fairness_questions():
362
+ """سوالات انصاف"""
363
+ st.header("📊 پرسشنامه ادراک انصاف")
364
+ st.markdown("**لطفاً میزان موافقت خود با جملات زیر را مشخص کنید:**")
365
+
366
+ questions = [
367
+ "قیمتی که به شما ارائه شد، منصفانه است.",
368
+ "قیمتی که به شما ارائه شد، معقول است.",
369
+ "قیمتی که به شما ارائه شد، قابل قبول است.",
370
+ "فرآیند و رویه قیمت‌گذاری پلتفرم قابل قبول است.",
371
+ "فرآیند و رویه قیمت‌گذاری پلتفرم منصفانه است.",
372
+ "فرآیند و رویه قیمت‌گذاری پلتفرم معقول است."
373
+ ]
374
+
375
+ answers = []
376
+ for i, question in enumerate(questions):
377
+ answer = create_likert_question(question, f"fairness_q{i}")
378
+ answers.append(answer)
379
+
380
+ if None not in answers:
381
+ st.session_state.fairness_answers = answers
382
+ if st.button("ارسال پاسخ‌ها", type="primary"):
383
+ all_data = {
384
+ "scenario_type": st.session_state.scenario_type,
385
+ "price": st.session_state.price,
386
+ **st.session_state.demographic_data,
387
+ "transparency_answers": st.session_state.transparency_answers,
388
+ "fairness_answers": st.session_state.fairness_answers
389
+ }
390
+
391
+ if save_to_sheet(all_data):
392
+ st.session_state.current_page = "thank_you"
393
+ st.rerun()
394
+
395
+ def thank_you_page():
396
+ """صفحه تشکر"""
397
+ st.success("✅ پاسخ‌های شما با موفقیت ثبت شد. با تشکر از مشارکت شما در این تحقیق!")
398
+ st.balloons()
399
+
400
+ if st.button("بازگشت به ابتدا"):
401
+ st.session_state.clear()
402
+ st.rerun()
403
+
404
+ # ========== مدیریت وضعیت و صفحه‌بندی ==========
405
+ if 'current_page' not in st.session_state:
406
+ st.session_state.current_page = "welcome"
407
+ st.session_state.scenario_type = random.choice(["control", "input", "counterfactual"])
408
+ st.session_state.price = 200000 # قیمت ثابت 200 هزار تومان
409
+
410
+ # نمایش صفحه فعلی
411
+ pages = {
412
+ "welcome": welcome_page,
413
+ "demographic": demographic_form,
414
+ "scenario_explanation": scenario_explanation,
415
+ "map_view": map_view,
416
+ "transparency_questions": transparency_questions,
417
+ "fairness_questions": fairness_questions,
418
+ "thank_you": thank_you_page
419
+ }
420
+
421
+ pages[st.session_state.current_page]()
422
+
423
  if __name__ == "__main__":
424
  main()