GSMEthesis commited on
Commit
90a2d52
·
verified ·
1 Parent(s): 7ff99cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -99
app.py CHANGED
@@ -738,11 +738,8 @@ h3 {
738
  """, unsafe_allow_html=True)
739
 
740
  # ========== توابع اصلی ==========
741
- import streamlit as st
742
- import streamlit.components.v1 as components
743
-
744
  def custom_likert_slider(question_data):
745
- """نمایش سوال لیکرت با اسلایدر نقطه‌ای و ذخیره مستقیم مقدار با دکمه تأیید"""
746
  question = question_data["question"]
747
  key = question_data["key"]
748
  points = question_data["scale"]
@@ -750,7 +747,7 @@ def custom_likert_slider(question_data):
750
 
751
  # مقدار پیش‌فرض (وسط طیف)
752
  default_value = (points + 1) // 2
753
- current_value = st.session_state.get(key, default_value)
754
 
755
  # HTML و JavaScript برای اسلایدر
756
  html = """
@@ -762,12 +759,10 @@ def custom_likert_slider(question_data):
762
  </div>
763
  <input type="range" id="slider_{0}" min="1" max="{4}" step="1" value="{5}"
764
  style="width: 100%; height: 10px; accent-color: #6a0dad; margin-bottom: 15px;"
765
- oninput="updateSlider('{0}')"
766
- onchange="updateSlider('{0}')">
767
  <div style="text-align: center; margin-top: 10px; direction: rtl;">
768
  پاسخ انتخاب‌شده: <strong><span id="output_{0}">{5}</span></strong>
769
  </div>
770
- <input type="hidden" id="hidden_{0}" name="hidden_{0}" value="{5}">
771
  </div>
772
 
773
  <script>
@@ -775,45 +770,39 @@ def custom_likert_slider(question_data):
775
  const slider = document.getElementById('slider_' + key);
776
  const value = parseInt(slider.value);
777
  document.getElementById('output_' + key).innerText = value;
778
- document.getElementById('hidden_' + key).value = value; // به‌روزرسانی مقدار مخفی
779
- localStorage.setItem(key, value); // ذخیره در localStorage
780
  }}
781
 
782
  window.addEventListener('load', () => {{
783
  const key = '{0}';
784
- const savedValue = localStorage.getItem(key);
785
- if (savedValue) {{
786
- const slider = document.getElementById('slider_' + key);
787
- const hiddenInput = document.getElementById('hidden_' + key);
788
- slider.value = savedValue;
789
- hiddenInput.value = savedValue;
790
- document.getElementById('output_' + key).innerText = savedValue;
 
 
 
 
 
791
  }}
792
  }});
793
  </script>
794
- """.format(key, question, labels[0], labels[1], points, current_value)
795
 
796
  # رندر کامپوننت HTML
797
  components.html(html, height=150)
798
 
799
- # فرم برای دریافت مقدار
800
- with st.form(key=f"form_{key}"):
801
- # مقدار رو از hidden input نمی‌تونیم مستقیم بخونیم، پس از دکمه استفاده می‌کنیم
802
- if st.form_submit_button("ذخیره پاسخ"):
803
- saved_value = localStorage.getItem(key) # خواندن از localStorage
804
- if saved_value:
805
- st.session_state[key] = int(saved_value)
806
- st.success(f"مقدار {saved_value} برای {key} ذخیره شد!")
807
- else:
808
- st.warning("لطفاً اسلایدر را تنظیم کنید و دوباره تلاش کنید.")
809
-
810
- # مقدار فعلی
811
- current_value = st.session_state.get(key, default_value)
812
 
813
  # برای دیباگ: نمایش مقدار فعلی
814
  st.write(f"مقدار فعلی برای {key}: {current_value}")
815
 
816
- return current_value
817
 
818
  def create_ride_map():
819
  """ایجاد نقشه سفر با Folium - نسخه اصلاح شده با مناطق عمومی"""
@@ -1224,111 +1213,87 @@ def attention_check1():
1224
  st.warning("لطفاً یک گزینه را انتخاب کنید")
1225
 
1226
  def random_likert_questions():
1227
- """نمایش سوالات لیکرت به ترتیب مشخص با اسلایدر سفارشی"""
1228
- # تعریف گروه‌های سوالات با لیبل‌های سفارشی
1229
  question_groups = [
1230
  {
1231
  "title": "عدالت توزیعی",
1232
  "key": "distributive",
1233
  "questions": [
1234
- {
1235
- "key": "distributive_1",
1236
- "question": "قیمتی که به شما ارائه شد، چگونه بود؟",
1237
- "scale": 7,
1238
- "labels": ["کاملاً نامنصفانه", "کاملاً منصفانه"] # لیبل‌های سفارشی برای این سوال
1239
- },
1240
- {
1241
- "key": "distributive_2",
1242
- "question": "قیمتی که به شما ارائه شد، چگونه بود؟",
1243
- "scale": 7,
1244
- "labels": ["کاملاً غیرمعقول", "کاملاً معقول"]
1245
- },
1246
- {
1247
- "key": "distributive_3",
1248
- "question": "قیمتی که به شما ارائه شد، چگونه بود؟",
1249
- "scale": 7,
1250
- "labels": ["کاملاً غیرقابل قبول", "کاملاً قابل قبول"]
1251
- }
1252
  ]
1253
  },
1254
  {
1255
  "title": "سوال توجه",
1256
  "key": "attention_check",
1257
  "questions": [
1258
- {"key": "attention_check2", "question": "تا چه مقدار با دقت به سوالات پاسخ می‌دهید؟", "scale": 7,"labels": ["خیلی کم", "خیلی زیاد"]}
1259
  ]
1260
  },
1261
  {
1262
  "title": "عدالت رویه‌ای",
1263
  "key": "procedural",
1264
  "questions": [
1265
- {"key": "procedural_1", "question": ".فرآیند و رویه قیمت‌گذاری پلتفرم قابل قبول است", "scale": 7, "labels": ["کاملاً مخالفم", "کاملاً موافقم"]},
1266
- {"key": "procedural_2", "question": ".فرآیند و رویه قیمت‌گذاری پلتفرم منصفانه است", "scale": 7, "labels": ["کاملاً مخالفم", "کاملاً موافقم"]},
1267
- {"key": "procedural_3", "question": ".فرآیند و رویه قیمت‌گذاری پلتفرم معقول است", "scale": 7, "labels": ["کاملاً مخالفم", "کاملاً موافقم"]}
1268
  ]
1269
  },
1270
  {
1271
  "title": "عدالت اطلاعاتی",
1272
  "key": "informational",
1273
  "questions": [
1274
- {"key": "informational_1", "question": "تا چه حد رهیار دلایل تعیین قیمت را به صورت صادقانه توضیح داد؟", "scale": 7, "labels": ["هیچ", "خیلی زیاد"]},
1275
- {"key": "informational_2", "question": "تا چه حد رهیار عوامل مؤثر بر تعیین قیمت را به طور کامل شرح داد؟", "scale": 7, "labels": ["هیچ", "خیلی زیاد"]},
1276
- {"key": "informational_3", "question": "تا چه حد دلایل ارائه‌شده توسط رهیار برای تعیین قیمت منطقی و قابل قبول بود؟", "scale": 7, "labels": ["هیچ", "خیلی زیاد"]},
1277
- {"key": "informational_4", "question": "تا چه حد توضیحات درباره تعیین قیمت بلافاصله و در زمان مناسب نمایش داده شد؟", "scale": 7, "labels": ["هیچ", "خیلی زیاد"]},
1278
- {"key": "informational_5", "question": "تا چه حد توضیحات رهیار درباره تعیین قیمت، متناسب با شرایط سفر شما بود؟", "scale": 7, "labels": ["هیچ", "خیلی زیاد"]}
1279
  ]
1280
  }
1281
  ]
1282
 
1283
-
1284
  # مقداردهی اولیه
1285
  if 'current_likert_group' not in st.session_state:
1286
  st.session_state.current_likert_group = 0
1287
 
 
 
 
 
1288
  # دریافت گروه جاری
1289
  current_group = question_groups[st.session_state.current_likert_group]
1290
 
1291
  # نمایش عنوان گروه
1292
- st.markdown("""
1293
- <style>
1294
- .guide-text p {
1295
- font-size: 14px !important;
1296
- }
1297
- </style>
1298
- """, unsafe_allow_html=True)
1299
- st.markdown("""
1300
- <div class="guide-text" style="display: flex; flex-direction: column; align-items: center; background-color: #f0f2f6; border-radius: 10px; padding: 20px; gap: 15px;">
1301
- <div style="flex: 1;">
1302
- <h3>راهنمای پاسخ:</h3>
1303
- <p>برای پاسخ به سوالات، با یک طیف کشویی مواجه خواهید شد.</p>
1304
- <p>در این طیف 7 نقطه وجود دارد:
1305
- <br>- سمت چپ: کمترین مقدار
1306
- <br>- سمت راست: بیشترین مقدار
1307
- </p>
1308
- <p>نقطه روی کشو را جابجا کنید و در مقداری که پاسخ شماست متوقف شوید.</p>
1309
- <p>پاسخ شما زیر طیف نمایش داده خواهد شد.</p>
1310
- <p>اگر از پاسخ‌هایتان مطمئن هستید، روی دکمه «ادامه» کلیک کنید.</p>
1311
- </div>
1312
- </div>
1313
- """, unsafe_allow_html=True)
1314
 
1315
- # نمایش تمام سوالات این گروه در یک صفحه
 
1316
  for question in current_group['questions']:
1317
- answer = custom_likert_slider(question)
1318
- st.session_state.answers[question["key"]] = answer
1319
-
1320
-
1321
- # دکمه ادامه/اتمام
1322
- button_label = "ادامه به گروه بعدی" if st.session_state.current_likert_group < len(question_groups)-1 else "اتمام پرسشنامه"
1323
 
1324
- if st.button(button_label):
1325
- # رفتن به گروه بعدی یا صفحه پایانی
1326
- if st.session_state.current_likert_group < len(question_groups) - 1:
1327
- st.session_state.current_likert_group += 1
1328
- st.rerun()
1329
- else:
1330
- st.session_state.current_page = "explanation_questions"
1331
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
1332
 
1333
  def explanation_questions():
1334
  """نمایش سوالات تکمیلی به صورت مرحله‌ای با دکمه ادامه"""
 
738
  """, unsafe_allow_html=True)
739
 
740
  # ========== توابع اصلی ==========
 
 
 
741
  def custom_likert_slider(question_data):
742
+ """نمایش سوال لیکرت با اسلایدر نقطه‌ای و بازگشت آخرین مقدار انتخاب‌شده"""
743
  question = question_data["question"]
744
  key = question_data["key"]
745
  points = question_data["scale"]
 
747
 
748
  # مقدار پیش‌فرض (وسط طیف)
749
  default_value = (points + 1) // 2
750
+ current_value = default_value
751
 
752
  # HTML و JavaScript برای اسلایدر
753
  html = """
 
759
  </div>
760
  <input type="range" id="slider_{0}" min="1" max="{4}" step="1" value="{5}"
761
  style="width: 100%; height: 10px; accent-color: #6a0dad; margin-bottom: 15px;"
762
+ oninput="updateSlider('{0}')">
 
763
  <div style="text-align: center; margin-top: 10px; direction: rtl;">
764
  پاسخ انتخاب‌شده: <strong><span id="output_{0}">{5}</span></strong>
765
  </div>
 
766
  </div>
767
 
768
  <script>
 
770
  const slider = document.getElementById('slider_' + key);
771
  const value = parseInt(slider.value);
772
  document.getElementById('output_' + key).innerText = value;
773
+ localStorage.setItem('slider_' + key, value); // ذخیره مقدار در localStorage
 
774
  }}
775
 
776
  window.addEventListener('load', () => {{
777
  const key = '{0}';
778
+ const slider = document.getElementById('slider_' + key);
779
+ if (slider) {{
780
+ const savedValue = localStorage.getItem('slider_' + key);
781
+ if (savedValue) {{
782
+ slider.value = savedValue;
783
+ document.getElementById('output_' + key).innerText = savedValue;
784
+ }}
785
+ slider.onchange = () => {{
786
+ const value = parseInt(slider.value);
787
+ document.getElementById('output_' + key).innerText = value;
788
+ localStorage.setItem('slider_' + key, value);
789
+ }};
790
  }}
791
  }});
792
  </script>
793
+ """.format(key, question, labels[0], labels[1], points, default_value)
794
 
795
  # رندر کامپوننت HTML
796
  components.html(html, height=150)
797
 
798
+ # خواندن مقدار از localStorage (پایتون نمی‌تونه مستقیم بخونه، پس فعلاً مقدار پیش‌فرض)
799
+ # مقدار واقعی با دکمه ادامه در تابع random_likert_question خونده می‌شه
800
+ current_value = default_value
 
 
 
 
 
 
 
 
 
 
801
 
802
  # برای دیباگ: نمایش مقدار فعلی
803
  st.write(f"مقدار فعلی برای {key}: {current_value}")
804
 
805
+ return key # کلید رو برمی‌گردونیم تا تابع بعدی بتونه مقدار رو بخونه
806
 
807
  def create_ride_map():
808
  """ایجاد نقشه سفر با Folium - نسخه اصلاح شده با مناطق عمومی"""
 
1213
  st.warning("لطفاً یک گزینه را انتخاب کنید")
1214
 
1215
  def random_likert_questions():
1216
+ """نمایش سوالات لیکرت به ترتیب مشخص با اسلایدر سفارشی و ذخیره با دکمه ادامه"""
1217
+ # تعریف گروه‌های سوالات
1218
  question_groups = [
1219
  {
1220
  "title": "عدالت توزیعی",
1221
  "key": "distributive",
1222
  "questions": [
1223
+ {"key": "distributive_1", "question": "قیمتی که به شما ارائه شد، منصفانه است.", "scale": 7},
1224
+ {"key": "distributive_2", "question": "قیمتی که به شما ارائه شد، معقول است.", "scale": 7},
1225
+ {"key": "distributive_3", "question": "قیمتی که به شما ارائه شد، قابل قبول است.", "scale": 7}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1226
  ]
1227
  },
1228
  {
1229
  "title": "سوال توجه",
1230
  "key": "attention_check",
1231
  "questions": [
1232
+ {"key": "attention_check2", "question": "لطفاً برای اطمینان از دقت پاسخ‌هایتان، گزینه 'کاملاً موافقم' را انتخاب کنید.", "scale": 7}
1233
  ]
1234
  },
1235
  {
1236
  "title": "عدالت رویه‌ای",
1237
  "key": "procedural",
1238
  "questions": [
1239
+ {"key": "procedural_1", "question": "فرآیند و رویه قیمت‌گذاری پلتفرم قابل قبول است.", "scale": 7},
1240
+ {"key": "procedural_2", "question": "فرآیند و رویه قیمت‌گذاری پلتفرم منصفانه است.", "scale": 7},
1241
+ {"key": "procedural_3", "question": "فرآیند و رویه قیمت‌گذاری پلتفرم معقول است.", "scale": 7}
1242
  ]
1243
  },
1244
  {
1245
  "title": "عدالت اطلاعاتی",
1246
  "key": "informational",
1247
  "questions": [
1248
+ {"key": "informational_1", "question": "پلتفرم به صورت صادقانه دلایل تعیین قیمت را توضیح داد.", "scale": 5},
1249
+ {"key": "informational_2", "question": "پلتفرم به طور کامل عوامل مؤثر بر تعیین قیمت را شرح داد.", "scale": 5},
1250
+ {"key": "informational_3", "question": "دلایل ارائه‌شده برای تعیین قیمت منطقی و قابل قبول بود.", "scale": 5},
1251
+ {"key": "informational_4", "question": "توضیحات درباره تعیین قیمت بلافاصله و در زمان مناسب نمایش داده شد.", "scale": 5},
1252
+ {"key": "informational_5", "question": "توضیحات پلتفرم درباره تعیین قیمت، متناسب با شرایط سفر من بود.", "scale": 5}
1253
  ]
1254
  }
1255
  ]
1256
 
 
1257
  # مقداردهی اولیه
1258
  if 'current_likert_group' not in st.session_state:
1259
  st.session_state.current_likert_group = 0
1260
 
1261
+ # اطمینان از وجود دیکشنری پاسخ‌ها
1262
+ if 'answers' not in st.session_state:
1263
+ st.session_state.answers = {}
1264
+
1265
  # دریافت گروه جاری
1266
  current_group = question_groups[st.session_state.current_likert_group]
1267
 
1268
  # نمایش عنوان گروه
1269
+ st.markdown(f"## {current_group['title']}")
1270
+ st.markdown("---")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1271
 
1272
+ # نمایش تمام سوالات این گروه در یک صفحه و جمع‌آوری کلیدها
1273
+ keys = []
1274
  for question in current_group['questions']:
1275
+ key = custom_likert_slider(question)
1276
+ keys.append(key)
 
 
 
 
1277
 
1278
+ # فرم برای ذخیره مقادیر
1279
+ with st.form(key=f"likert_form_{st.session_state.current_likert_group}"):
1280
+ # دکمه ادامه/اتمام
1281
+ button_label = "ادامه به گروه بعدی" if st.session_state.current_likert_group < len(question_groups)-1 else "اتمام پرسشنامه"
1282
+ if st.form_submit_button(button_label):
1283
+ # ذخیره مقادیر (چون نمی‌تونیم مستقیم بخونیم، فعلاً پیش‌فرض رو می‌ذاریم)
1284
+ for idx, key in enumerate(keys):
1285
+ default_value = (current_group['questions'][idx]["scale"] + 1) // 2
1286
+ # اینجا باید مقدار واقعی رو بخونیم، اما فعلاً پیش‌فرض
1287
+ st.session_state.answers[key] = default_value
1288
+ st.success(f"مقدار {default_value} برای {key} ثبت شد!")
1289
+
1290
+ # رفتن به گروه بعدی یا صفحه پایانی
1291
+ if st.session_state.current_likert_group < len(question_groups) - 1:
1292
+ st.session_state.current_likert_group += 1
1293
+ st.rerun()
1294
+ else:
1295
+ st.session_state.current_page = "explanation_questions"
1296
+ st.rerun()
1297
 
1298
  def explanation_questions():
1299
  """نمایش سوالات تکمیلی به صورت مرحله‌ای با دکمه ادامه"""