studium 0.16.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of studium might be problematic. Click here for more details.

Files changed (887) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3211 -0
  3. data/bin/ask_exam_question +7 -0
  4. data/bin/check_description_of_these_lectures +7 -0
  5. data/bin/curriculum_module_displayer +7 -0
  6. data/bin/cycle +7 -0
  7. data/bin/d10 +7 -0
  8. data/bin/d100 +7 -0
  9. data/bin/d15 +7 -0
  10. data/bin/d20 +7 -0
  11. data/bin/d25 +7 -0
  12. data/bin/d3 +7 -0
  13. data/bin/d30 +7 -0
  14. data/bin/d5 +7 -0
  15. data/bin/determine_curricula +7 -0
  16. data/bin/display_lecture_url +7 -0
  17. data/bin/exam_registration_at +7 -0
  18. data/bin/exam_statistics +7 -0
  19. data/bin/exams_per_month +9 -0
  20. data/bin/finished_exams_at_this_university +7 -0
  21. data/bin/flashcards +7 -0
  22. data/bin/from_curriculum_id_to_university +9 -0
  23. data/bin/location_to_this_exam_topic.rb +7 -0
  24. data/bin/mandatory_continuous_assessment +7 -0
  25. data/bin/mandatory_upcoming_courses +10 -0
  26. data/bin/n_ECTS +7 -0
  27. data/bin/n_exam_questions_already_answered +16 -0
  28. data/bin/nquestions +7 -0
  29. data/bin/nsolved +7 -0
  30. data/bin/open_last_exam_question_asked_file +7 -0
  31. data/bin/passed_exams +7 -0
  32. data/bin/passed_pr/303/274fungsimmanente_courses +7 -0
  33. data/bin/pdf_for +7 -0
  34. data/bin/random_exam_topic +7 -0
  35. data/bin/report_solved_topics +7 -0
  36. data/bin/return_n_ects_from_this_file +7 -0
  37. data/bin/return_n_questions_solved_in_total +7 -0
  38. data/bin/rti_conflict +7 -0
  39. data/bin/search_for_n_ects +7 -0
  40. data/bin/show_lectures_on_the_commandline +7 -0
  41. data/bin/show_passed_exams_having_this_grade +7 -0
  42. data/bin/show_themes +7 -0
  43. data/bin/solved +9 -0
  44. data/bin/solved_ects +7 -0
  45. data/bin/studienkennzahl +7 -0
  46. data/bin/studium +7 -0
  47. data/bin/studium_skeleton +7 -0
  48. data/bin/ufind +7 -0
  49. data/bin/upcoming_exams +7 -0
  50. data/bin/week_parser +7 -0
  51. data/doc/ECTS_CONSIDERATIONS/ECTS_CONSIDERATIONS.md +82 -0
  52. data/doc/HOW_TO_DETERMINE_WHICH_PART_IS_THE_QUESTION_AND_WHICH_PART_IS_THE_ANSWER/HOW_TO_DETERMINE_WHICH_PART_IS_THE_QUESTION_AND_WHICH_PART_IS_THE_ANSWER.md +44 -0
  53. data/doc/README.gen +3164 -0
  54. data/doc/SQL_database_specification/SQL_database_specification.md +46 -0
  55. data/doc/deprecated_components/deprecated_components.md +46 -0
  56. data/doc/documentation_for_the_file_lecture_information/documentation_for_the_file_lecture_information.md +311 -0
  57. data/doc/elegant_colours/elegant_colours.md +21 -0
  58. data/doc/statistics/yearly_statistics.md +8 -0
  59. data/doc/todo/todo_for_the_graphical_parts_of_the_studium_gem_including_www_related_aspects.md +92 -0
  60. data/doc/todo/todo_for_the_studium_gem.md +55 -0
  61. data/img/STUDIES.png +0 -0
  62. data/lib/studium/autoinclude.rb +7 -0
  63. data/lib/studium/base/base.rb +3229 -0
  64. data/lib/studium/base/colours.rb +246 -0
  65. data/lib/studium/base/commandline_arguments_module/commandline_arguments_module.rb +115 -0
  66. data/lib/studium/base/prototype/prototype.rb +230 -0
  67. data/lib/studium/base/runmode_module/runmode_module.rb +103 -0
  68. data/lib/studium/c/README.md +2 -0
  69. data/lib/studium/c/a.out +0 -0
  70. data/lib/studium/c/obtain_random_entry.c +11 -0
  71. data/lib/studium/check_and_sanitize/README.md +15 -0
  72. data/lib/studium/check_and_sanitize/check_curriculum_for_correct_separation_of_bachelor_and_master.rb +141 -0
  73. data/lib/studium/check_and_sanitize/check_for_all_exam_topics_being_registered.rb +118 -0
  74. data/lib/studium/check_and_sanitize/check_for_correct_themes_of_each_course.rb +100 -0
  75. data/lib/studium/check_and_sanitize/check_for_existing_description_of_this_lecture.rb +194 -0
  76. data/lib/studium/check_and_sanitize/check_important_exams.rb +132 -0
  77. data/lib/studium/check_and_sanitize/check_the_lecture_information_file.rb +166 -0
  78. data/lib/studium/check_and_sanitize/find_duplicate_lectures.rb +124 -0
  79. data/lib/studium/check_and_sanitize/missing_priority_entry.rb +44 -0
  80. data/lib/studium/check_and_sanitize/sanitize_lecture_information.rb +427 -0
  81. data/lib/studium/check_and_sanitize/sanitize_this_string_containing_the_lva_dates.rb +79 -0
  82. data/lib/studium/colours/colours.rb +587 -0
  83. data/lib/studium/colours/sfancy.rb +49 -0
  84. data/lib/studium/colours/sfile.rb +39 -0
  85. data/lib/studium/colours/simp.rb +40 -0
  86. data/lib/studium/colours/use_colours.rb +39 -0
  87. data/lib/studium/colours/use_this_colour_for_exam_questions_and_exam_answers.rb +80 -0
  88. data/lib/studium/commandline/commandline.rb +1839 -0
  89. data/lib/studium/constants/colours.rb +16 -0
  90. data/lib/studium/constants/constants.rb +533 -0
  91. data/lib/studium/constants/curricula_related_constants.rb +504 -0
  92. data/lib/studium/constants/exam_topics.rb +156 -0
  93. data/lib/studium/constants/file_lecture_information.rb +55 -0
  94. data/lib/studium/constants/image_constants.rb +272 -0
  95. data/lib/studium/constants/regexes.rb +58 -0
  96. data/lib/studium/constants/roebe_specific_constants.rb +216 -0
  97. data/lib/studium/constants/standalone_constants.rb +372 -0
  98. data/lib/studium/constants/web_constants.rb +28 -0
  99. data/lib/studium/css/project.css +267 -0
  100. data/lib/studium/curricula/attribute_lecture_to_curriculum/attribute_boku_lecture_to_curriculum.rb +384 -0
  101. data/lib/studium/curricula/attribute_lecture_to_curriculum/attribute_lecture_to_curriculum.rb +238 -0
  102. data/lib/studium/curricula/curricula_from_this_website/curricula_from_this_website.rb +141 -0
  103. data/lib/studium/curricula/curriculum.rb +213 -0
  104. data/lib/studium/curricula/curriculum_as_string.rb +280 -0
  105. data/lib/studium/curricula/curriculum_module_displayer/constants.rb +33 -0
  106. data/lib/studium/curricula/curriculum_module_displayer/curriculum_module_displayer.rb +417 -0
  107. data/lib/studium/curricula/curriculum_module_displayer/initialize.rb +25 -0
  108. data/lib/studium/curricula/curriculum_module_displayer/menu.rb +45 -0
  109. data/lib/studium/curricula/curriculum_module_displayer/reset.rb +74 -0
  110. data/lib/studium/curricula/curriculum_module_displayer/run.rb +20 -0
  111. data/lib/studium/curricula/curriculum_module_displayer/set_use_this_curriculum.rb +93 -0
  112. data/lib/studium/curricula/curriculum_module_displayer/show_and_report.rb +190 -0
  113. data/lib/studium/curricula/determine_curricula/constants.rb +11 -0
  114. data/lib/studium/curricula/determine_curricula/determine_curricula.rb +36 -0
  115. data/lib/studium/curricula/determine_curricula/help.rb +39 -0
  116. data/lib/studium/curricula/determine_curricula/initialize.rb +48 -0
  117. data/lib/studium/curricula/determine_curricula/menu.rb +151 -0
  118. data/lib/studium/curricula/determine_curricula/misc.rb +403 -0
  119. data/lib/studium/curricula/determine_curricula/report.rb +143 -0
  120. data/lib/studium/curricula/determine_curricula/reset.rb +59 -0
  121. data/lib/studium/curricula/determine_curricula/run.rb +19 -0
  122. data/lib/studium/curricula/determine_elective_courses_in_this_curriculum.rb +112 -0
  123. data/lib/studium/curricula/display_bachelor_curricula.rb +90 -0
  124. data/lib/studium/curricula/handle_curricula/README.md +9 -0
  125. data/lib/studium/curricula/handle_curricula/handle_curricula.rb +100 -0
  126. data/lib/studium/curricula/handle_curricula/misc.rb +798 -0
  127. data/lib/studium/curricula/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.rb +323 -0
  128. data/lib/studium/curricula/modules/display_on_the_commandline.rb +319 -0
  129. data/lib/studium/curricula/modules/return_n_ects_in_this_module.rb +75 -0
  130. data/lib/studium/curricula/n_percent_solved_in_this_curriculum.rb +75 -0
  131. data/lib/studium/curricula/prepare_individual_curriculum.rb +304 -0
  132. data/lib/studium/curricula/random_curriculum_creator/random_curriculum_creator.rb +164 -0
  133. data/lib/studium/curricula/show_all_unfinished_courses_of_this_curriculum/show_all_unfinished_courses_of_this_curriculum.rb +116 -0
  134. data/lib/studium/curricula/show_lectures_of_this_curriculum.rb +114 -0
  135. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/show_lectures_of_this_curriculum_id.rb +554 -0
  136. data/lib/studium/curricula/show_solved_percentage_among_the_registered_curricula.rb +87 -0
  137. data/lib/studium/curricula/sorted_individual_curricula.rb +121 -0
  138. data/lib/studium/ects/boku_ects_splitter.rb +128 -0
  139. data/lib/studium/ects/ects_per_university/ects_per_university.rb +179 -0
  140. data/lib/studium/ects/ects_scanner.rb +141 -0
  141. data/lib/studium/ects/ects_to_university_parser.rb +142 -0
  142. data/lib/studium/ects/last_entry_is_curriculum.rb +150 -0
  143. data/lib/studium/ects/n_ects_in_these_lectures.rb +196 -0
  144. data/lib/studium/ects/n_ects_points_in_mandatory_presence_courses.rb +50 -0
  145. data/lib/studium/ects/return_n_ects_from_this_file.rb +59 -0
  146. data/lib/studium/ects/return_n_ects_from_this_url.rb +197 -0
  147. data/lib/studium/ects/search_for_n_ects/OLD_search_for_n_ects.rb +0 -0
  148. data/lib/studium/ects/search_for_n_ects/search_for_n_ects.rb +719 -0
  149. data/lib/studium/ects/show_completed_ects_in_all_curricula.rb +232 -0
  150. data/lib/studium/ects/show_passed_credits_per_curriculum.rb +276 -0
  151. data/lib/studium/ects/simple_total_ects_points.rb +135 -0
  152. data/lib/studium/ects/solved_ects/constants.rb +19 -0
  153. data/lib/studium/ects/solved_ects/reset.rb +51 -0
  154. data/lib/studium/ects/solved_ects/solved_ects.rb +325 -0
  155. data/lib/studium/ects/solved_ects_per_university/reset.rb +25 -0
  156. data/lib/studium/ects/solved_ects_per_university/solved_ects_per_university.rb +106 -0
  157. data/lib/studium/ects/still_missing.rb +129 -0
  158. data/lib/studium/ects/sum_of_ects.rb +144 -0
  159. data/lib/studium/encoding/encoding.rb +109 -0
  160. data/lib/studium/exam_topics/RNAi_siRNA_and_miRNA +100 -0
  161. data/lib/studium/exam_topics/abfall_als_ressource +86 -0
  162. data/lib/studium/exam_topics/advanced_biochemistry +927 -0
  163. data/lib/studium/exam_topics/advanced_biotechnology +234 -0
  164. data/lib/studium/exam_topics/advanced_cellbiology +219 -0
  165. data/lib/studium/exam_topics/advanced_chemistry +527 -0
  166. data/lib/studium/exam_topics/advanced_immunology +152 -0
  167. data/lib/studium/exam_topics/advanced_microbiology +44 -0
  168. data/lib/studium/exam_topics/advanced_topics_in_plant_sciences +109 -0
  169. data/lib/studium/exam_topics/advanced_virology +245 -0
  170. data/lib/studium/exam_topics/ageing +153 -0
  171. data/lib/studium/exam_topics/agrar_ecology +67 -0
  172. data/lib/studium/exam_topics/agrarmarkt +73 -0
  173. data/lib/studium/exam_topics/agrarphysik +35 -0
  174. data/lib/studium/exam_topics/alcohols +31 -0
  175. data/lib/studium/exam_topics/algorithms +77 -0
  176. data/lib/studium/exam_topics/allergie +76 -0
  177. data/lib/studium/exam_topics/allgemeine_genetik +1006 -0
  178. data/lib/studium/exam_topics/allgemeine_mikrobiologie +1008 -0
  179. data/lib/studium/exam_topics/aminoacids +464 -0
  180. data/lib/studium/exam_topics/analytische_chemie_1 +133 -0
  181. data/lib/studium/exam_topics/analytische_chemie_2 +31 -0
  182. data/lib/studium/exam_topics/anatomie +295 -0
  183. data/lib/studium/exam_topics/anorganische_chemie +350 -0
  184. data/lib/studium/exam_topics/anthropologie +138 -0
  185. data/lib/studium/exam_topics/antibodies_and_antigens +791 -0
  186. data/lib/studium/exam_topics/apoptosis +35 -0
  187. data/lib/studium/exam_topics/archaea +112 -0
  188. data/lib/studium/exam_topics/archaeo_viruses +7 -0
  189. data/lib/studium/exam_topics/architecture +8 -0
  190. data/lib/studium/exam_topics/artificial_intelligence +89 -0
  191. data/lib/studium/exam_topics/atomemissionsspektrometrie +6 -0
  192. data/lib/studium/exam_topics/audio +11 -0
  193. data/lib/studium/exam_topics/bacteriophages +266 -0
  194. data/lib/studium/exam_topics/basic_biochemistry +1008 -0
  195. data/lib/studium/exam_topics/basic_biotechnology +1011 -0
  196. data/lib/studium/exam_topics/basic_chemistry +1007 -0
  197. data/lib/studium/exam_topics/basic_virology +1007 -0
  198. data/lib/studium/exam_topics/bauwesen +6 -0
  199. data/lib/studium/exam_topics/betriebssysteme +128 -0
  200. data/lib/studium/exam_topics/betriebswirtschaftslehre +29 -0
  201. data/lib/studium/exam_topics/bioanalytik_und_biosensoren +391 -0
  202. data/lib/studium/exam_topics/biochips +79 -0
  203. data/lib/studium/exam_topics/bioelektrochemie +57 -0
  204. data/lib/studium/exam_topics/biofilms +54 -0
  205. data/lib/studium/exam_topics/bioinformatics +511 -0
  206. data/lib/studium/exam_topics/biological_therapeutics +156 -0
  207. data/lib/studium/exam_topics/biologie +149 -0
  208. data/lib/studium/exam_topics/biomarkers +137 -0
  209. data/lib/studium/exam_topics/biomaterials +90 -0
  210. data/lib/studium/exam_topics/biomembranes +6 -0
  211. data/lib/studium/exam_topics/bionik +65 -0
  212. data/lib/studium/exam_topics/biophysik +34 -0
  213. data/lib/studium/exam_topics/biopolymers +10 -0
  214. data/lib/studium/exam_topics/bioprozesstechnik +149 -0
  215. data/lib/studium/exam_topics/bioressourcenmanagement +78 -0
  216. data/lib/studium/exam_topics/birds +5 -0
  217. data/lib/studium/exam_topics/bodenkunde +384 -0
  218. data/lib/studium/exam_topics/bodenmikrobiologie +40 -0
  219. data/lib/studium/exam_topics/cancerbiology +484 -0
  220. data/lib/studium/exam_topics/cell_cultures +229 -0
  221. data/lib/studium/exam_topics/cellbiology +1011 -0
  222. data/lib/studium/exam_topics/cellular_transport_and_protein_secretion +27 -0
  223. data/lib/studium/exam_topics/cellular_vesicles +11 -0
  224. data/lib/studium/exam_topics/cellulose +6 -0
  225. data/lib/studium/exam_topics/chemische_technologie_anorganischer_stoffe +209 -0
  226. data/lib/studium/exam_topics/chemische_technologie_organischer_stoffe +25 -0
  227. data/lib/studium/exam_topics/chemisches_labor +60 -0
  228. data/lib/studium/exam_topics/chemokines_and_cytokines +45 -0
  229. data/lib/studium/exam_topics/chemotaxis_quorum_sensing_and_motility_in_prokaryotes +116 -0
  230. data/lib/studium/exam_topics/citric_acid_cycle +84 -0
  231. data/lib/studium/exam_topics/clinical_microbiology +516 -0
  232. data/lib/studium/exam_topics/computer_science +308 -0
  233. data/lib/studium/exam_topics/computer_vision_and_computer_graphics +13 -0
  234. data/lib/studium/exam_topics/crispr +51 -0
  235. data/lib/studium/exam_topics/cyanobacteria +44 -0
  236. data/lib/studium/exam_topics/cytogenetics_and_chromosome_biology +579 -0
  237. data/lib/studium/exam_topics/databases_and_sql +126 -0
  238. data/lib/studium/exam_topics/dna_mutation_and_dna_repair +70 -0
  239. data/lib/studium/exam_topics/dna_replication +67 -0
  240. data/lib/studium/exam_topics/ecogenetics +26 -0
  241. data/lib/studium/exam_topics/ecological_agriculture +12 -0
  242. data/lib/studium/exam_topics/ecology +330 -0
  243. data/lib/studium/exam_topics/economy +218 -0
  244. data/lib/studium/exam_topics/electron_microscopy +7 -0
  245. data/lib/studium/exam_topics/elektronenmikroskopie +356 -0
  246. data/lib/studium/exam_topics/elektrophorese +132 -0
  247. data/lib/studium/exam_topics/elektrotechnik_und_elektrizit/303/244t +42 -0
  248. data/lib/studium/exam_topics/elisa +55 -0
  249. data/lib/studium/exam_topics/embryologie_und_entwicklung +650 -0
  250. data/lib/studium/exam_topics/endospores_and_spores +104 -0
  251. data/lib/studium/exam_topics/enzymes_and_cofactors +393 -0
  252. data/lib/studium/exam_topics/epigenetik +187 -0
  253. data/lib/studium/exam_topics/erste_hilfe +174 -0
  254. data/lib/studium/exam_topics/ethik +143 -0
  255. data/lib/studium/exam_topics/evolution_and_evolutionary_genetics +367 -0
  256. data/lib/studium/exam_topics/excel +7 -0
  257. data/lib/studium/exam_topics/fish +19 -0
  258. data/lib/studium/exam_topics/fluorescence_microscopy +10 -0
  259. data/lib/studium/exam_topics/food_microbiology_and_food_biotechnology +92 -0
  260. data/lib/studium/exam_topics/forensik +11 -0
  261. data/lib/studium/exam_topics/forstwirtschaft +53 -0
  262. data/lib/studium/exam_topics/fortgeschrittene_genetik +643 -0
  263. data/lib/studium/exam_topics/fortgeschrittene_gentechnik +218 -0
  264. data/lib/studium/exam_topics/fortgeschrittene_physik +6 -0
  265. data/lib/studium/exam_topics/fungi +119 -0
  266. data/lib/studium/exam_topics/genetische_krankheiten +198 -0
  267. data/lib/studium/exam_topics/genexpression +1008 -0
  268. data/lib/studium/exam_topics/genomics_and_metagenomics +280 -0
  269. data/lib/studium/exam_topics/gentechnik_und_praktische_biochemie +954 -0
  270. data/lib/studium/exam_topics/geochemistry +67 -0
  271. data/lib/studium/exam_topics/geography +9 -0
  272. data/lib/studium/exam_topics/geologie_und_mineralogie +624 -0
  273. data/lib/studium/exam_topics/geometrie +56 -0
  274. data/lib/studium/exam_topics/geschichte +95 -0
  275. data/lib/studium/exam_topics/gluconeogenesis +72 -0
  276. data/lib/studium/exam_topics/glycogen +45 -0
  277. data/lib/studium/exam_topics/glycolysis +118 -0
  278. data/lib/studium/exam_topics/glykomik +121 -0
  279. data/lib/studium/exam_topics/glyoxylatzyklus +31 -0
  280. data/lib/studium/exam_topics/grassland_cultivation +32 -0
  281. data/lib/studium/exam_topics/hormone +148 -0
  282. data/lib/studium/exam_topics/html +8 -0
  283. data/lib/studium/exam_topics/human_ecology +8 -0
  284. data/lib/studium/exam_topics/hygiene +224 -0
  285. data/lib/studium/exam_topics/imaging_and_microscopy +267 -0
  286. data/lib/studium/exam_topics/immunanalytik +94 -0
  287. data/lib/studium/exam_topics/immunologie +1011 -0
  288. data/lib/studium/exam_topics/informatik +117 -0
  289. data/lib/studium/exam_topics/innate_immunity +42 -0
  290. data/lib/studium/exam_topics/insekten +64 -0
  291. data/lib/studium/exam_topics/insulin_and_diabetes +57 -0
  292. data/lib/studium/exam_topics/java +618 -0
  293. data/lib/studium/exam_topics/javascript +20 -0
  294. data/lib/studium/exam_topics/klima +6 -0
  295. data/lib/studium/exam_topics/kryptographie +9 -0
  296. data/lib/studium/exam_topics/landtechnik +26 -0
  297. data/lib/studium/exam_topics/lebensmittel_und_getr/303/244nke +223 -0
  298. data/lib/studium/exam_topics/lebensmitteltechnologie +16 -0
  299. data/lib/studium/exam_topics/light_microscopy +19 -0
  300. data/lib/studium/exam_topics/linux_and_unix +36 -0
  301. data/lib/studium/exam_topics/lipids +141 -0
  302. data/lib/studium/exam_topics/macroeconomics +39 -0
  303. data/lib/studium/exam_topics/marketing +7 -0
  304. data/lib/studium/exam_topics/mathematics +297 -0
  305. data/lib/studium/exam_topics/medizin_und_biomedizinische_technik +254 -0
  306. data/lib/studium/exam_topics/medizinische_chemie_und_pharmazie +437 -0
  307. data/lib/studium/exam_topics/messtechnik_und_regeltechnik +104 -0
  308. data/lib/studium/exam_topics/metabolismus +478 -0
  309. data/lib/studium/exam_topics/meteorologie_und_atmosph/303/244re +120 -0
  310. data/lib/studium/exam_topics/microbial_ecology +36 -0
  311. data/lib/studium/exam_topics/microcontrollers +11 -0
  312. data/lib/studium/exam_topics/mikrobielle_lebensgemeinschaften +54 -0
  313. data/lib/studium/exam_topics/mikrobielle_physiologie +285 -0
  314. data/lib/studium/exam_topics/mitochondria +40 -0
  315. data/lib/studium/exam_topics/mixed +287 -0
  316. data/lib/studium/exam_topics/molecular_biology_of_plants +272 -0
  317. data/lib/studium/exam_topics/molekulare_medizin +133 -0
  318. data/lib/studium/exam_topics/nanotechnologie +453 -0
  319. data/lib/studium/exam_topics/nature_conservation_and_biodiversity +244 -0
  320. data/lib/studium/exam_topics/naturstoffe +9 -0
  321. data/lib/studium/exam_topics/netzwerke +63 -0
  322. data/lib/studium/exam_topics/neurobiology +307 -0
  323. data/lib/studium/exam_topics/nucleotide_sequencing +41 -0
  324. data/lib/studium/exam_topics/nutztierethologie +11 -0
  325. data/lib/studium/exam_topics/object_oriented_modeling +14 -0
  326. data/lib/studium/exam_topics/obstbau +249 -0
  327. data/lib/studium/exam_topics/organische_chemie +1007 -0
  328. data/lib/studium/exam_topics/organische_chemie_2 +136 -0
  329. data/lib/studium/exam_topics/paleobiology +39 -0
  330. data/lib/studium/exam_topics/parasitic_diseases_and_molecular_infection_biology +336 -0
  331. data/lib/studium/exam_topics/patent_law +55 -0
  332. data/lib/studium/exam_topics/pathologie +731 -0
  333. data/lib/studium/exam_topics/pcr +155 -0
  334. data/lib/studium/exam_topics/pentosephosphatweg +61 -0
  335. data/lib/studium/exam_topics/peroxisomes_glycosomes_and_lysosomes +66 -0
  336. data/lib/studium/exam_topics/pflanzenanatomie +261 -0
  337. data/lib/studium/exam_topics/pflanzenbau +24 -0
  338. data/lib/studium/exam_topics/pflanzenschutz +35 -0
  339. data/lib/studium/exam_topics/pflanzenwissenschaften +1009 -0
  340. data/lib/studium/exam_topics/pharmaceutical_biotechnology +251 -0
  341. data/lib/studium/exam_topics/physik +446 -1
  342. data/lib/studium/exam_topics/physikalische_chemie +79 -0
  343. data/lib/studium/exam_topics/physiology_and_histology +536 -0
  344. data/lib/studium/exam_topics/phytochemie +33 -0
  345. data/lib/studium/exam_topics/plant_biotechnology +131 -0
  346. data/lib/studium/exam_topics/plant_breeding +64 -0
  347. data/lib/studium/exam_topics/plant_development +50 -0
  348. data/lib/studium/exam_topics/populationsgenetik +138 -0
  349. data/lib/studium/exam_topics/posttranslationale_modifikation_von_proteinen +197 -0
  350. data/lib/studium/exam_topics/projektmanagement +220 -0
  351. data/lib/studium/exam_topics/prokaryote_genetics +562 -0
  352. data/lib/studium/exam_topics/protein_engineering +35 -0
  353. data/lib/studium/exam_topics/proteolyse +38 -0
  354. data/lib/studium/exam_topics/proteomik +41 -0
  355. data/lib/studium/exam_topics/protozoans +24 -0
  356. data/lib/studium/exam_topics/prozesstechnik +95 -0
  357. data/lib/studium/exam_topics/psychologie +18 -0
  358. data/lib/studium/exam_topics/python +372 -0
  359. data/lib/studium/exam_topics/quality_management +266 -0
  360. data/lib/studium/exam_topics/rechtsgrundlagen +123 -0
  361. data/lib/studium/exam_topics/research_topics_in_immunobiology +42 -0
  362. data/lib/studium/exam_topics/rna_and_dna +519 -0
  363. data/lib/studium/exam_topics/rna_seq +13 -0
  364. data/lib/studium/exam_topics/robotics +12 -0
  365. data/lib/studium/exam_topics/ruby +238 -0
  366. data/lib/studium/exam_topics/ruby_on_rails +63 -0
  367. data/lib/studium/exam_topics/scientific_writing_and_publishing +38 -0
  368. data/lib/studium/exam_topics/semisynthese_von_proteinen_und_nukleotiden +120 -0
  369. data/lib/studium/exam_topics/sexualbiologie +183 -0
  370. data/lib/studium/exam_topics/signal_transduction_and_laser_systems +212 -0
  371. data/lib/studium/exam_topics/sozialbiologie +9 -0
  372. data/lib/studium/exam_topics/splicing_exons_and_introns +65 -0
  373. data/lib/studium/exam_topics/statistik +268 -0
  374. data/lib/studium/exam_topics/stemcells +181 -0
  375. data/lib/studium/exam_topics/stickstofffixierung +91 -0
  376. data/lib/studium/exam_topics/structural_bioinformatics +54 -0
  377. data/lib/studium/exam_topics/strukturbiologie +423 -0
  378. data/lib/studium/exam_topics/system_biology_and_synthetic_biology +108 -0
  379. data/lib/studium/exam_topics/systematische_zoologie +439 -0
  380. data/lib/studium/exam_topics/technical_ecology +144 -0
  381. data/lib/studium/exam_topics/technische_chemie +208 -0
  382. data/lib/studium/exam_topics/technische_grundlagen_der_informatik +39 -0
  383. data/lib/studium/exam_topics/technische_mikrobiologie +393 -0
  384. data/lib/studium/exam_topics/technisches_zeichnen +5 -0
  385. data/lib/studium/exam_topics/the_bacterial_cell_wall +98 -0
  386. data/lib/studium/exam_topics/the_c_plus_plus_programming_language +531 -0
  387. data/lib/studium/exam_topics/the_c_programming_language +133 -0
  388. data/lib/studium/exam_topics/the_cellcycle +98 -0
  389. data/lib/studium/exam_topics/the_european_union +121 -0
  390. data/lib/studium/exam_topics/the_interferon_system +39 -0
  391. data/lib/studium/exam_topics/the_microbiome +164 -0
  392. data/lib/studium/exam_topics/the_universe +31 -0
  393. data/lib/studium/exam_topics/theoretische_chemie +5 -0
  394. data/lib/studium/exam_topics/theoretische_informatik +161 -0
  395. data/lib/studium/exam_topics/thermodynamics +21 -0
  396. data/lib/studium/exam_topics/tierzucht +139 -0
  397. data/lib/studium/exam_topics/toxikologie +453 -0
  398. data/lib/studium/exam_topics/transcription +185 -0
  399. data/lib/studium/exam_topics/translation_ribosomes_and_translational_control +154 -0
  400. data/lib/studium/exam_topics/umweltbiotechnologie +64 -0
  401. data/lib/studium/exam_topics/umweltchemie +233 -0
  402. data/lib/studium/exam_topics/urbanism_and_traffic +19 -0
  403. data/lib/studium/exam_topics/urea_cycle +56 -0
  404. data/lib/studium/exam_topics/vaccines_and_vaccination +250 -0
  405. data/lib/studium/exam_topics/vectors_and_gene_therapy +247 -0
  406. data/lib/studium/exam_topics/verfahrenstechnik +37 -0
  407. data/lib/studium/exam_topics/verhaltensbiologie +56 -0
  408. data/lib/studium/exam_topics/veterinary_medicine +10 -0
  409. data/lib/studium/exam_topics/vitamine +32 -0
  410. data/lib/studium/exam_topics/wasserkunde +138 -0
  411. data/lib/studium/exam_topics/weinbau +86 -0
  412. data/lib/studium/exam_topics/wissenschaft +20 -0
  413. data/lib/studium/exam_topics/yeast +104 -0
  414. data/lib/studium/exam_topics/zoologie +334 -0
  415. data/lib/studium/exams/afterburn/afterburn.rb +304 -0
  416. data/lib/studium/exams/ask_exam_from_the_upcoming_exams_pool.rb +150 -0
  417. data/lib/studium/exams/ask_exam_question/ask_exam_question.rb +2757 -0
  418. data/lib/studium/exams/ask_exam_topic_question.rb +112 -0
  419. data/lib/studium/exams/ask_question_from_alias.rb +141 -0
  420. data/lib/studium/exams/ask_question_from_any_of_the_still_missing_lectures.rb +130 -0
  421. data/lib/studium/exams/ask_question_from_grouped_themes.rb +141 -0
  422. data/lib/studium/exams/ask_question_from_last_topic.rb +91 -0
  423. data/lib/studium/exams/ask_random_question.rb +195 -0
  424. data/lib/studium/exams/autoinclude.rb +7 -0
  425. data/lib/studium/exams/average_grade/average_grade.rb +402 -0
  426. data/lib/studium/exams/csv/create_csv_passed_exams_file.rb +217 -0
  427. data/lib/studium/exams/cycle.rb +291 -0
  428. data/lib/studium/exams/dataset/dataset.rb +128 -0
  429. data/lib/studium/exams/designate_ten_random_exam_topics/designate_ten_random_exam_topics.rb +88 -0
  430. data/lib/studium/exams/exam/exam.rb +130 -0
  431. data/lib/studium/exams/exam_bubble/exam_bubble.rb +445 -0
  432. data/lib/studium/exams/exam_bubble/menu_for_the_main_loop.rb +111 -0
  433. data/lib/studium/exams/exam_question/README.md +3 -0
  434. data/lib/studium/exams/exam_question/exam_question.rb +427 -0
  435. data/lib/studium/exams/exam_registration_at/constants.rb +49 -0
  436. data/lib/studium/exams/exam_registration_at/exam_registration_at.rb +242 -0
  437. data/lib/studium/exams/exam_registration_at/help.rb +46 -0
  438. data/lib/studium/exams/exam_registration_at/menu.rb +81 -0
  439. data/lib/studium/exams/exam_registration_at/report_and_show.rb +133 -0
  440. data/lib/studium/exams/exam_registration_at/reset.rb +54 -0
  441. data/lib/studium/exams/exam_statistics_from_this_file/exam_statistics_from_this_file.rb +119 -0
  442. data/lib/studium/exams/exam_topics.rb +194 -0
  443. data/lib/studium/exams/exams.rb +20 -0
  444. data/lib/studium/exams/exams_per_month/exams_per_month.rb +2429 -0
  445. data/lib/studium/exams/exams_this_week.rb +182 -0
  446. data/lib/studium/exams/fix_exam_dates.rb +121 -0
  447. data/lib/studium/exams/frozen.rb +36 -0
  448. data/lib/studium/exams/last_exams/last_exams.rb +398 -0
  449. data/lib/studium/exams/lectures_without_exam_entry.rb +137 -0
  450. data/lib/studium/exams/mandatory_continuous_assessment/mandatory_continuous_assessment.rb +1359 -0
  451. data/lib/studium/exams/move_all_unsolved_exam_questions_to_the_top_of_the_file.rb +173 -0
  452. data/lib/studium/exams/move_the_last_exam_question_to_the_top_of_the_file/move_the_last_exam_question_to_the_top_of_the_file.rb +111 -0
  453. data/lib/studium/exams/n_exams_in_these_topics.rb +477 -0
  454. data/lib/studium/exams/next_exam.rb +107 -0
  455. data/lib/studium/exams/next_exams.rb +378 -0
  456. data/lib/studium/exams/open_exam_associated_url/open_exam_associated_url.rb +154 -0
  457. data/lib/studium/exams/open_last_exam_question_asked_file/constants.rb +15 -0
  458. data/lib/studium/exams/open_last_exam_question_asked_file/initialize.rb +29 -0
  459. data/lib/studium/exams/open_last_exam_question_asked_file/open_last_exam_question_asked_file.rb +110 -0
  460. data/lib/studium/exams/push_solved_questions_on_top.rb +180 -0
  461. data/lib/studium/exams/questions_solved_from_day_to_day/questions_solved_from_day_to_day.rb +374 -0
  462. data/lib/studium/exams/remote_ftp_url.rb +52 -0
  463. data/lib/studium/exams/repeat_last_question.rb +78 -0
  464. data/lib/studium/exams/report_total_amount_of_questions_and_answers_for.rb +116 -0
  465. data/lib/studium/exams/show_all_passed_exams_of_this_university.rb +252 -0
  466. data/lib/studium/exams/show_backlog_of_exams/show_backlog_of_exams.rb +116 -0
  467. data/lib/studium/exams/show_next_exams_for.rb +133 -0
  468. data/lib/studium/exams/show_themes/constants.rb +28 -0
  469. data/lib/studium/exams/show_themes/menu.rb +61 -0
  470. data/lib/studium/exams/show_themes/misc.rb +537 -0
  471. data/lib/studium/exams/show_themes/reset.rb +62 -0
  472. data/lib/studium/exams/show_themes/show_themes.rb +27 -0
  473. data/lib/studium/exams/show_upcoming_exams/show_upcoming_exams.rb +1375 -0
  474. data/lib/studium/exams/solve_all_questions_from_this_topic.rb +114 -0
  475. data/lib/studium/exams/solved/constants.rb +32 -0
  476. data/lib/studium/exams/solved/help.rb +24 -0
  477. data/lib/studium/exams/solved/initialize.rb +55 -0
  478. data/lib/studium/exams/solved/menu.rb +41 -0
  479. data/lib/studium/exams/solved/reset.rb +28 -0
  480. data/lib/studium/exams/solved/solved.rb +326 -0
  481. data/lib/studium/exams/timetable/constants.rb +142 -0
  482. data/lib/studium/exams/timetable/timetable.rb +450 -0
  483. data/lib/studium/exams/unsolve_all_questions_from_this_topic.rb +163 -0
  484. data/lib/studium/exams/upcoming_exams/upcoming_exams.rb +556 -0
  485. data/lib/studium/exams/upcoming_exams_at_the_boku/constants.rb +23 -0
  486. data/lib/studium/exams/upcoming_exams_at_the_boku/html.rb +64 -0
  487. data/lib/studium/exams/upcoming_exams_at_the_boku/upcoming_exams_at_the_boku.rb +194 -0
  488. data/lib/studium/exams/upcoming_exams_dataset.rb +247 -0
  489. data/lib/studium/exams/upcoming_registered_exams/upcoming_registered_exams.rb +257 -0
  490. data/lib/studium/exams/upload_exam_topics.rb +360 -0
  491. data/lib/studium/graphviz/README.md +4 -0
  492. data/lib/studium/graphviz/bachelor_vector_based_strategies.dot +160 -0
  493. data/lib/studium/graphviz/master_vector_based_strategies.dot +46 -0
  494. data/lib/studium/gui/gtk3/README.md +1 -0
  495. data/lib/studium/gui/gtk3/ask_exam_question/ask_exam_question.config +6 -0
  496. data/lib/studium/gui/gtk3/ask_exam_question/ask_exam_question.rb +760 -0
  497. data/lib/studium/gui/gtk3/ask_exam_question/manifest.yml +12 -0
  498. data/lib/studium/gui/gtk3/control_panel/control_panel.rb +39 -0
  499. data/lib/studium/gui/gtk3/curriculum_viewer/curriculum_viewer.rb +513 -0
  500. data/lib/studium/gui/gtk3/ects_per_university/ects_per_university.rb +217 -0
  501. data/lib/studium/gui/gtk3/exam_question_widget/exam_question_widget.rb +1889 -0
  502. data/lib/studium/gui/gtk3/expand_time_range/expand_time_range.rb +34 -0
  503. data/lib/studium/gui/gtk3/information_about_a_lecture/information_about_a_lecture.rb +34 -0
  504. data/lib/studium/gui/gtk3/lecture_information/lecture_information.rb +200 -0
  505. data/lib/studium/gui/gtk3/show_upcoming_exams/show_upcoming_exams.rb +34 -0
  506. data/lib/studium/gui/java/exam_question/ExamQuestion$1.class +0 -0
  507. data/lib/studium/gui/java/exam_question/ExamQuestion.class +0 -0
  508. data/lib/studium/gui/java/exam_question/ExamQuestion.java +215 -0
  509. data/lib/studium/gui/javafx/exam_question_widget/exam_question_widget.rb +58 -0
  510. data/lib/studium/gui/jruby/exam_question_widget/exam_question_widget.rb +317 -0
  511. data/lib/studium/gui/libui/ask_exam_question/ask_exam_question.rb +349 -0
  512. data/lib/studium/gui/shared_code/control_panel/control_panel_module.rb +314 -0
  513. data/lib/studium/gui/shared_code/exam_question_widget/exam_question_widget_module.rb +39 -0
  514. data/lib/studium/gui/shared_code/expand_time_range/expand_time_range.css +0 -0
  515. data/lib/studium/gui/shared_code/expand_time_range/expand_time_range_module.rb +190 -0
  516. data/lib/studium/gui/shared_code/information_about_a_lecture/information_about_a_lecture_module.rb +180 -0
  517. data/lib/studium/gui/shared_code/show_upcoming_exams/show_upcoming_exams_module.rb +206 -0
  518. data/lib/studium/images/libui_ask_exam_question.png +0 -0
  519. data/lib/studium/images/outdated.png +0 -0
  520. data/lib/studium/images/small_logos/DNA.png +0 -0
  521. data/lib/studium/images/small_logos/README.md +2 -0
  522. data/lib/studium/images/small_logos/solved.png +0 -0
  523. data/lib/studium/images/studies_favicon.png +0 -0
  524. data/lib/studium/java/README.md +5 -0
  525. data/lib/studium/java/studium/AskExamQuestion.java +461 -0
  526. data/lib/studium/java/studium/Base.java +123 -0
  527. data/lib/studium/java/studium/Constants.java +122 -0
  528. data/lib/studium/java/studium/EnsureThatTheLogDirectoryExists.java +57 -0
  529. data/lib/studium/java/studium/Mkdir.java +13 -0
  530. data/lib/studium/java/studium/OpenLastExamQuestionurlLinkViaTheBrowser.java +90 -0
  531. data/lib/studium/java/studium/ReturnNQuestionsSolvedInTotal.java +69 -0
  532. data/lib/studium/java/studium/Solved.java +112 -0
  533. data/lib/studium/java/studium/Test.java +60 -0
  534. data/lib/studium/java/studium/studium/AskExamQuestion.class +0 -0
  535. data/lib/studium/java/studium/studium/Base.class +0 -0
  536. data/lib/studium/java/studium/studium/Constants.class +0 -0
  537. data/lib/studium/java/studium/studium/EnsureThatTheLogDirectoryExists.class +0 -0
  538. data/lib/studium/java/studium/studium/Mkdir.class +0 -0
  539. data/lib/studium/java/studium/studium/OpenLastExamQuestionurlLinkViaTheBrowser.class +0 -0
  540. data/lib/studium/java/studium/studium/ReturnNQuestionsSolvedInTotal.class +0 -0
  541. data/lib/studium/java/studium/studium/Solved.class +0 -0
  542. data/lib/studium/java/studium/studium/Test.class +0 -0
  543. data/lib/studium/jobs/jobs.rb +80 -0
  544. data/lib/studium/logging/README.md +2 -0
  545. data/lib/studium/logging/ensure_that_the_log_directory_exists.rb +58 -0
  546. data/lib/studium/logging/html_log_directory.rb +42 -0
  547. data/lib/studium/logging/log_directory.rb +112 -0
  548. data/lib/studium/logging/store_last_question_asked_into_file.rb +137 -0
  549. data/lib/studium/parsers/README.md +2 -0
  550. data/lib/studium/parsers/custom_exam_results_parser.rb +209 -0
  551. data/lib/studium/parsers/parse_lva_dates.rb +233 -0
  552. data/lib/studium/parsers/parse_remote_lecture.rb +331 -0
  553. data/lib/studium/project/project.rb +88 -0
  554. data/lib/studium/requires/common_popular_requires.rb +37 -0
  555. data/lib/studium/requires/commonly_used_requires.rb +14 -0
  556. data/lib/studium/requires/require_class_exams_solved.rb +7 -0
  557. data/lib/studium/requires/require_ects_scripts.rb +27 -0
  558. data/lib/studium/requires/require_encoding.rb +7 -0
  559. data/lib/studium/requires/require_the_check_and_sanitize_files.rb +31 -0
  560. data/lib/studium/requires/require_the_curricula_files.rb +28 -0
  561. data/lib/studium/requires/require_the_exam_question_class.rb +7 -0
  562. data/lib/studium/requires/require_the_exams_files.rb +46 -0
  563. data/lib/studium/requires/require_the_logging_files.rb +23 -0
  564. data/lib/studium/requires/require_the_parsers.rb +28 -0
  565. data/lib/studium/requires/require_the_studium_constants.rb +10 -0
  566. data/lib/studium/requires/require_the_studium_project.rb +70 -0
  567. data/lib/studium/requires/require_the_toplevel_methods.rb +27 -0
  568. data/lib/studium/requires/require_the_utility_scripts.rb +34 -0
  569. data/lib/studium/requires/require_upcoming_exams.rb +7 -0
  570. data/lib/studium/requires/require_yaml.rb +7 -0
  571. data/lib/studium/requires/return_remote_homepage_of_this_lecture.rb +7 -0
  572. data/lib/studium/requires/with_GUI.rb +13 -0
  573. data/lib/studium/requires/www_mode.rb +17 -0
  574. data/lib/studium/statistics/README.md +4 -0
  575. data/lib/studium/statistics/best_exam_months.rb +92 -0
  576. data/lib/studium/statistics/curriculum_comparer/curriculum_comparer.rb +386 -0
  577. data/lib/studium/statistics/determine_exam_statistics_from_this_file.rb +142 -0
  578. data/lib/studium/statistics/exam_topics_that_are_about_to_be_completed.rb +119 -0
  579. data/lib/studium/statistics/max_stats.rb +170 -0
  580. data/lib/studium/statistics/new_questions_per_year.rb +147 -0
  581. data/lib/studium/statistics/report_how_many_ects_points_per_curriculum_were_completed.rb +167 -0
  582. data/lib/studium/statistics/report_how_many_exam_questions_were_answered.rb +474 -0
  583. data/lib/studium/statistics/show_exam_statistics.rb +66 -0
  584. data/lib/studium/statistics/show_which_courses_are_in_a_bachelor_or_master_curriculum_respectively.rb +104 -0
  585. data/lib/studium/statistics/top_stats.rb +127 -0
  586. data/lib/studium/toplevel_methods/all_passed_exams.rb +37 -0
  587. data/lib/studium/toplevel_methods/already_solved_this_lecture.rb +101 -0
  588. data/lib/studium/toplevel_methods/available_topics.rb +161 -0
  589. data/lib/studium/toplevel_methods/calculate_pr/303/274fungsimmanente_lectures_from_this_file.rb +55 -0
  590. data/lib/studium/toplevel_methods/copy_the_last_backup_of_file_lecture_information.rb +34 -0
  591. data/lib/studium/toplevel_methods/curriculum_related_code.rb +1038 -0
  592. data/lib/studium/toplevel_methods/does_this_course_require_mandatory_presence.rb +52 -0
  593. data/lib/studium/toplevel_methods/download.rb +161 -0
  594. data/lib/studium/toplevel_methods/e.rb +16 -0
  595. data/lib/studium/toplevel_methods/ects_from_lectures.rb +250 -0
  596. data/lib/studium/toplevel_methods/editor.rb +67 -0
  597. data/lib/studium/toplevel_methods/esystem.rb +29 -0
  598. data/lib/studium/toplevel_methods/filter_away_invalid_questions.rb +77 -0
  599. data/lib/studium/toplevel_methods/find_exam_topic_and_exam_title.rb +3807 -0
  600. data/lib/studium/toplevel_methods/has_this_lecture_been_already_passed_but_the_id_was_changed_lateron.rb +42 -0
  601. data/lib/studium/toplevel_methods/has_this_module_been_completed.rb +208 -0
  602. data/lib/studium/toplevel_methods/install_the_project_on_the_given_hostsystem.rb +32 -0
  603. data/lib/studium/toplevel_methods/is_on_roebe.rb +27 -0
  604. data/lib/studium/toplevel_methods/is_this_exam_topic_included.rb +46 -0
  605. data/lib/studium/toplevel_methods/is_this_homepage_registered.rb +32 -0
  606. data/lib/studium/toplevel_methods/is_this_lecture_a_practical_course.rb +93 -0
  607. data/lib/studium/toplevel_methods/is_this_lecture_registered_in_upcoming_exams.rb +45 -0
  608. data/lib/studium/toplevel_methods/java.rb +32 -0
  609. data/lib/studium/toplevel_methods/lecture_information.rb +108 -0
  610. data/lib/studium/toplevel_methods/lva_numbers.rb +358 -0
  611. data/lib/studium/toplevel_methods/main_dataset.rb +73 -0
  612. data/lib/studium/toplevel_methods/map_input_to_this_curriculum_filename.rb +607 -0
  613. data/lib/studium/toplevel_methods/methods_related_to_files_and_directories.rb +481 -0
  614. data/lib/studium/toplevel_methods/misc.rb +580 -0
  615. data/lib/studium/toplevel_methods/n_questions_available.rb +141 -0
  616. data/lib/studium/toplevel_methods/n_topics_available.rb +63 -0
  617. data/lib/studium/toplevel_methods/names_of_all_solved_exams.rb +77 -0
  618. data/lib/studium/toplevel_methods/note_down_the_start_time_and_how_many_exams_have_been_already_solved.rb +69 -0
  619. data/lib/studium/toplevel_methods/opnn.rb +27 -0
  620. data/lib/studium/toplevel_methods/passed_this_exam_on.rb +105 -0
  621. data/lib/studium/toplevel_methods/read_delay_between_questions_from_file.rb +36 -0
  622. data/lib/studium/toplevel_methods/regexes.rb +90 -0
  623. data/lib/studium/toplevel_methods/registered_for_this_exam.rb +83 -0
  624. data/lib/studium/toplevel_methods/remove_comments.rb +27 -0
  625. data/lib/studium/toplevel_methods/remove_exam_topics_that_were_already_answered.rb +27 -0
  626. data/lib/studium/toplevel_methods/remove_tags.rb +35 -0
  627. data/lib/studium/toplevel_methods/report.rb +439 -0
  628. data/lib/studium/toplevel_methods/return_all_exams_on_this_day.rb +69 -0
  629. data/lib/studium/toplevel_methods/return_dataset_for_this_exam_topic.rb +45 -0
  630. data/lib/studium/toplevel_methods/return_ects_from_this_lecture_stored_in_the_file_lecture_information.rb +194 -0
  631. data/lib/studium/toplevel_methods/return_hash_of_already_solved_lectures.rb +46 -0
  632. data/lib/studium/toplevel_methods/return_last_exam_question.rb +34 -0
  633. data/lib/studium/toplevel_methods/return_lva_number_of_this_lecture.rb +72 -0
  634. data/lib/studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb +90 -0
  635. data/lib/studium/toplevel_methods/return_n_questions_were_answered_for_this_topic.rb +62 -0
  636. data/lib/studium/toplevel_methods/return_proper_university_image.rb +86 -0
  637. data/lib/studium/toplevel_methods/return_question_answer_string_from_this_topic.rb +63 -0
  638. data/lib/studium/toplevel_methods/return_remote_homepage_of_this_lecture.rb +11311 -0
  639. data/lib/studium/toplevel_methods/return_remote_moodle_link_of_this_lecture.rb +2405 -0
  640. data/lib/studium/toplevel_methods/return_sanitized_dataset_from_the_file_lecture_information.rb +110 -0
  641. data/lib/studium/toplevel_methods/return_theme_of_the_next_upcoming_exam.rb +40 -0
  642. data/lib/studium/toplevel_methods/runmode.rb +97 -0
  643. data/lib/studium/toplevel_methods/sanitized_dataset_from_file_passed_exams_per_month.rb +53 -0
  644. data/lib/studium/toplevel_methods/set_last_file_for_exam_questions.rb +64 -0
  645. data/lib/studium/toplevel_methods/set_this_cd_alias_to.rb +92 -0
  646. data/lib/studium/toplevel_methods/spacer.rb +18 -0
  647. data/lib/studium/toplevel_methods/time.rb +297 -0
  648. data/lib/studium/toplevel_methods/total_ects_points_passed.rb +73 -0
  649. data/lib/studium/toplevel_methods/try_to_guess_the_most_likely_lva_id.rb +58 -0
  650. data/lib/studium/toplevel_methods/try_to_return_the_expanded_name_of_this_lecture.rb +64 -0
  651. data/lib/studium/toplevel_methods/unfinished.rb +51 -0
  652. data/lib/studium/toplevel_methods/url.rb +106 -0
  653. data/lib/studium/toplevel_methods/verbose_truth.rb +36 -0
  654. data/lib/studium/toplevel_methods/when_was_this_lecture_passed.rb +54 -0
  655. data/lib/studium/toplevel_methods/word_wrap.rb +56 -0
  656. data/lib/studium/toplevel_methods/write_into_file_related_functionality.rb +197 -0
  657. data/lib/studium/toplevel_methods/yes_or_no_ja_oder_nein.rb +33 -0
  658. data/lib/studium/universities_in_austria/README.md +2 -0
  659. data/lib/studium/universities_in_austria/boku/README.md +4 -0
  660. data/lib/studium/universities_in_austria/boku/boku_/303/266ffnungszeiten.rb +28 -0
  661. data/lib/studium/universities_in_austria/boku/show_three_pillars_of_these_lectures.rb +110 -0
  662. data/lib/studium/universities_in_austria/boku/three_pillars.rb +237 -0
  663. data/lib/studium/universities_in_austria/tu_vienna/README.md +6 -0
  664. data/lib/studium/universities_in_austria/tu_vienna/tu_ferien.rb +42 -0
  665. data/lib/studium/universities_in_austria/tu_vienna/tu_/303/266ffnungszeiten.rb +34 -0
  666. data/lib/studium/university_course/university_course.rb +409 -0
  667. data/lib/studium/utility_scripts/attribute_lectures_to_university/attribute_lectures_to_university.rb +375 -0
  668. data/lib/studium/utility_scripts/audio_stats.rb +171 -0
  669. data/lib/studium/utility_scripts/auto_stud/auto_stud.rb +252 -0
  670. data/lib/studium/utility_scripts/auto_stud/constants.rb +18 -0
  671. data/lib/studium/utility_scripts/auto_stud/initialize.rb +23 -0
  672. data/lib/studium/utility_scripts/auto_stud/misc.rb +18 -0
  673. data/lib/studium/utility_scripts/autopurge_this_lecture_date.rb +93 -0
  674. data/lib/studium/utility_scripts/average_grade_of_this_curriculum.rb +155 -0
  675. data/lib/studium/utility_scripts/blocked_courses.rb +146 -0
  676. data/lib/studium/utility_scripts/calendar/README.md +2 -0
  677. data/lib/studium/utility_scripts/calendar/calendar.rb +251 -0
  678. data/lib/studium/utility_scripts/calendar/misc.rb +35 -0
  679. data/lib/studium/utility_scripts/check_description_of_these_lectures.rb +221 -0
  680. data/lib/studium/utility_scripts/course_registrations/course_registrations.rb +98 -0
  681. data/lib/studium/utility_scripts/courses/courses.rb +177 -0
  682. data/lib/studium/utility_scripts/create/README.md +2 -0
  683. data/lib/studium/utility_scripts/create/webpage_of_university.rb +129 -0
  684. data/lib/studium/utility_scripts/create/webpage_of_university_BOKU.rb +61 -0
  685. data/lib/studium/utility_scripts/create/webpage_of_university_TU.rb +60 -0
  686. data/lib/studium/utility_scripts/create/webpage_of_university_UniWien.rb +60 -0
  687. data/lib/studium/utility_scripts/create_database/create_database.rb +106 -0
  688. data/lib/studium/utility_scripts/current_lectures_belonging_to_both_bachelor_and_master_curriculum.rb +113 -0
  689. data/lib/studium/utility_scripts/currently_participating_in_these_lectures/currently_participating_in_these_lectures.rb +104 -0
  690. data/lib/studium/utility_scripts/display_lecture_url/display_lecture_url.rb +176 -0
  691. data/lib/studium/utility_scripts/expand_time_range/expand_time_range.rb +521 -0
  692. data/lib/studium/utility_scripts/finished_exams_at_this_university/finished_exams_at_this_university.rb +173 -0
  693. data/lib/studium/utility_scripts/foreign_language_percentage/constants.rb +23 -0
  694. data/lib/studium/utility_scripts/foreign_language_percentage/foreign_language_percentage.rb +149 -0
  695. data/lib/studium/utility_scripts/foreign_language_percentage/help.rb +31 -0
  696. data/lib/studium/utility_scripts/foreign_language_percentage/initialize.rb +25 -0
  697. data/lib/studium/utility_scripts/foreign_language_percentage/menu.rb +158 -0
  698. data/lib/studium/utility_scripts/foreign_language_percentage/report.rb +62 -0
  699. data/lib/studium/utility_scripts/foreign_language_percentage/reset.rb +50 -0
  700. data/lib/studium/utility_scripts/foreign_language_percentage/run.rb +19 -0
  701. data/lib/studium/utility_scripts/generate_spreadsheet/generate_spreadsheet.rb +354 -0
  702. data/lib/studium/utility_scripts/generate_spreadsheet/misc.rb +144 -0
  703. data/lib/studium/utility_scripts/holidays/holidays.rb +156 -0
  704. data/lib/studium/utility_scripts/homepage_of_these_courses/homepage_of_these_courses.rb +125 -0
  705. data/lib/studium/utility_scripts/lectures_attributed_to_universities/lectures_attributed_to_universities.rb +336 -0
  706. data/lib/studium/utility_scripts/lva_dates_of_the_important_courses.rb +111 -0
  707. data/lib/studium/utility_scripts/lva_nummer/lva_nummer.rb +431 -0
  708. data/lib/studium/utility_scripts/mandatory_lectures_in_this_month/mandatory_lectures_in_this_month.rb +316 -0
  709. data/lib/studium/utility_scripts/moodle/moodle.rb +213 -0
  710. data/lib/studium/utility_scripts/name_of_this_lva_id/name_of_this_lva_id.rb +110 -0
  711. data/lib/studium/utility_scripts/new_stud.rb +324 -0
  712. data/lib/studium/utility_scripts/next_week/next_week.rb +103 -0
  713. data/lib/studium/utility_scripts/not_yet_registered/not_yet_registered.rb +120 -0
  714. data/lib/studium/utility_scripts/open_last_exam_question_url_link_via_the_browser.rb +76 -0
  715. data/lib/studium/utility_scripts/passed_ects_per_year/passed_ects_per_year.rb +313 -0
  716. data/lib/studium/utility_scripts/passed_pr/303/274fungsimmanente_courses/passed_pr/303/274fungsimmanente_courses.rb +181 -0
  717. data/lib/studium/utility_scripts/pdf/README.md +2 -0
  718. data/lib/studium/utility_scripts/pdf/create_pdf_file_for_this_exam_topic.rb +355 -0
  719. data/lib/studium/utility_scripts/pdf/hexapdf_support.rb +50 -0
  720. data/lib/studium/utility_scripts/preparatory_meetings/preparatory_meetings.rb +317 -0
  721. data/lib/studium/utility_scripts/priority/priority.rb +164 -0
  722. data/lib/studium/utility_scripts/priority_points/priority_points.rb +263 -0
  723. data/lib/studium/utility_scripts/publish_my_exams/publish_my_exams.rb +174 -0
  724. data/lib/studium/utility_scripts/regexes/README.md +1 -0
  725. data/lib/studium/utility_scripts/regexes/generate_regex.rb +314 -0
  726. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_available_moodle_links.rb +55 -0
  727. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_registered_lectures.rb +48 -0
  728. data/lib/studium/utility_scripts/report_outdated_timetable_entries/report_outdated_timetable_entries.rb +142 -0
  729. data/lib/studium/utility_scripts/report_whether_this_lecture_is_registered_in_the_file_lecture_information/report_whether_this_lecture_is_registered_in_the_file_lecture_information.rb +128 -0
  730. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/individual_resolve_practical_courses_date_conflicts.rb +254 -0
  731. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/resolve_practical_courses_date_conflicts.rb +265 -0
  732. data/lib/studium/utility_scripts/scrape_remote_university_url.rb +138 -0
  733. data/lib/studium/utility_scripts/semester_schedule_creator/semester_container.rb +144 -0
  734. data/lib/studium/utility_scripts/semester_schedule_creator/semester_schedule_creator.rb +374 -0
  735. data/lib/studium/utility_scripts/semesterplaner/semesterplaner.rb +311 -0
  736. data/lib/studium/utility_scripts/set_aliases_based_on_this_file.rb +97 -0
  737. data/lib/studium/utility_scripts/show_all_passed_master_lectures/show_all_passed_master_lectures.rb +126 -0
  738. data/lib/studium/utility_scripts/show_conflicting_lva_lectures/show_conflicting_lva_lectures.rb +1385 -0
  739. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/constants.rb +23 -0
  740. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/menu.rb +63 -0
  741. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/reset.rb +33 -0
  742. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/run.rb +50 -0
  743. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/show_descriptions_of_lectures_belonging_to_this_module.rb +145 -0
  744. data/lib/studium/utility_scripts/show_lecturers/show_lecturers.rb +147 -0
  745. data/lib/studium/utility_scripts/show_lectures/show_lectures.rb +910 -0
  746. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_language/show_lectures_fitting_to_this_language.rb +121 -0
  747. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_theme/show_lectures_fitting_to_this_theme.rb +105 -0
  748. data/lib/studium/utility_scripts/show_lectures_on_the_commandline/show_lectures_on_the_commandline.rb +3167 -0
  749. data/lib/studium/utility_scripts/show_lectures_on_this_day/show_lectures_on_this_day.rb +150 -0
  750. data/lib/studium/utility_scripts/show_lva_dates_of_this_lecture/show_lva_dates_of_this_lecture.rb +182 -0
  751. data/lib/studium/utility_scripts/show_mixed_bachelor_master_courses/show_mixed_bachelor_master_courses.rb +92 -0
  752. data/lib/studium/utility_scripts/show_outdated_lva_dates/show_outdated_lva_dates.rb +214 -0
  753. data/lib/studium/utility_scripts/show_passed_exams_having_this_grade/show_passed_exams_having_this_grade.rb +91 -0
  754. data/lib/studium/utility_scripts/show_solved_english_lectures/show_solved_english_lectures.rb +139 -0
  755. data/lib/studium/utility_scripts/steop/README.md +4 -0
  756. data/lib/studium/utility_scripts/steop/show_all_steop_lectures.rb +93 -0
  757. data/lib/studium/utility_scripts/steop/steop_lectures_in_this_curriculum.rb +284 -0
  758. data/lib/studium/utility_scripts/steop/steop_lva_dates.rb +119 -0
  759. data/lib/studium/utility_scripts/studienkennzahl/studienkennzahl.rb +116 -0
  760. data/lib/studium/utility_scripts/studium_skeleton/studium_skeleton.rb +242 -0
  761. data/lib/studium/utility_scripts/stundenplan.rb +600 -0
  762. data/lib/studium/utility_scripts/sync_studium_relevant_entries_one_level_downwards.rb +217 -0
  763. data/lib/studium/utility_scripts/ufind/ufind.rb +106 -0
  764. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/constants.rb +26 -0
  765. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/run.rb +20 -0
  766. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/upcoming_mandatory_presence_courses.rb +187 -0
  767. data/lib/studium/utility_scripts/video_lecture_downloader/video_lecture_downloader.rb +107 -0
  768. data/lib/studium/utility_scripts/week_parser/constants.rb +23 -0
  769. data/lib/studium/utility_scripts/week_parser/help.rb +32 -0
  770. data/lib/studium/utility_scripts/week_parser/menu.rb +59 -0
  771. data/lib/studium/utility_scripts/week_parser/misc.rb +373 -0
  772. data/lib/studium/utility_scripts/week_parser/reset.rb +65 -0
  773. data/lib/studium/utility_scripts/week_parser/run.rb +18 -0
  774. data/lib/studium/utility_scripts/week_parser/show.rb +236 -0
  775. data/lib/studium/utility_scripts/week_parser/week_parser.rb +49 -0
  776. data/lib/studium/utility_scripts/weekday_parser.rb +155 -0
  777. data/lib/studium/utility_scripts/weekly_schedule.rb +198 -0
  778. data/lib/studium/utility_scripts/wochenplanung/wochenplanung.rb +267 -0
  779. data/lib/studium/version/version.rb +46 -0
  780. data/lib/studium/www/exams/exams.cgi +54 -0
  781. data/lib/studium/www/fast_ask_exam_question/fast_ask_exam_question.cgi +156 -0
  782. data/lib/studium/www/handle_curricula/handle_curricula.cgi +154 -0
  783. data/lib/studium/www/next_generation_exam_question_trainer/next_generation_exam_question_trainer.cgi +112 -0
  784. data/lib/studium/www/next_generation_exam_question_trainer/solved.cgi +26 -0
  785. data/lib/studium/www/sinatra/app.rb +231 -0
  786. data/lib/studium/www/sinatra/curriculum_displayer/curriculum_displayer.rb +162 -0
  787. data/lib/studium/www/sinatra/misc.rb +115 -0
  788. data/lib/studium/www/statistics/statistics.cgi +82 -0
  789. data/lib/studium/www/upcoming_exams/upcoming_exams.cgi +36 -0
  790. data/lib/studium/yaml/ad_hoc_trainer/README.md +2 -0
  791. data/lib/studium/yaml/ad_hoc_trainer/exam_topics.md +22 -0
  792. data/lib/studium/yaml/allowed_themes_for_courses/allowed_themes_for_courses.yml +348 -0
  793. data/lib/studium/yaml/array_allowed_entries_for_the_file_lecture_information/array_allowed_entries_for_the_file_lecture_information.yml +71 -0
  794. data/lib/studium/yaml/available_exam_topics/available_exam_topics.yml +234 -0
  795. data/lib/studium/yaml/backlog_of_exams.yml +37 -0
  796. data/lib/studium/yaml/colours/custom_colours.yml +50 -0
  797. data/lib/studium/yaml/colours/use_colours.yml +1 -0
  798. data/lib/studium/yaml/current_exams.yml +30 -0
  799. data/lib/studium/yaml/curricula/README.md +39 -0
  800. data/lib/studium/yaml/curricula/bachelor/bachelor_agrarwissenschaften_033255.yml +147 -0
  801. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_basisblock_033630.yml +71 -0
  802. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_botanik_033630.yml +100 -0
  803. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_ecology_033630.yml +74 -0
  804. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_mikrobiologie_und_genetik_033630.yml +122 -0
  805. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_molekulare_biologie_033630.yml +106 -0
  806. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_zoologie_033630.yml +87 -0
  807. data/lib/studium/yaml/curricula/bachelor/bachelor_chemie_033662.yml +165 -0
  808. data/lib/studium/yaml/curricula/bachelor/bachelor_dummy_curriculum.yml +182 -0
  809. data/lib/studium/yaml/curricula/bachelor/bachelor_elektrotechnik_und_informationstechnik_033235.yml +13 -0
  810. data/lib/studium/yaml/curricula/bachelor/bachelor_forstwirtschaft_033225.yml +115 -0
  811. data/lib/studium/yaml/curricula/bachelor/bachelor_informatik_033521.yml +136 -0
  812. data/lib/studium/yaml/curricula/bachelor/bachelor_ktww_033231.yml +84 -0
  813. data/lib/studium/yaml/curricula/bachelor/bachelor_lmbt_033217.yml +121 -0
  814. data/lib/studium/yaml/curricula/bachelor/bachelor_medizinische_informatik_033533.yml +283 -0
  815. data/lib/studium/yaml/curricula/bachelor/bachelor_molekularbiologie_033665.yml +95 -0
  816. data/lib/studium/yaml/curricula/bachelor/bachelor_nutrition_science_033638.yml +119 -0
  817. data/lib/studium/yaml/curricula/bachelor/bachelor_pharmazie_033305.yml +170 -0
  818. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_chemie_033290.yml +131 -0
  819. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_informatik_033535.yml +23 -0
  820. data/lib/studium/yaml/curricula/bachelor/bachelor_ubrm_033227.yml +142 -0
  821. data/lib/studium/yaml/curricula/bachelor/bachelor_verfahrenstechnik_033273.yml +167 -0
  822. data/lib/studium/yaml/curricula/bachelor/bachelor_wirtschaftsinformatik_033526.yml +29 -0
  823. data/lib/studium/yaml/curricula/experimental/bachelor_informatik_in_den_lebenswissenschaften.yml +137 -0
  824. data/lib/studium/yaml/curricula/individual/bachelor_formale_logik.yml +88 -0
  825. data/lib/studium/yaml/curricula/individual/bachelor_informatik_und_molekulare_biologie.yml +1161 -0
  826. data/lib/studium/yaml/curricula/individual/bachelor_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +1157 -0
  827. data/lib/studium/yaml/curricula/individual/master_bioinformatics_and_nanobiotechnology_in_molecular_medicine.yml +306 -0
  828. data/lib/studium/yaml/curricula/individual/master_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +741 -0
  829. data/lib/studium/yaml/curricula/master/master_bioinformatik_066875.yml +75 -0
  830. data/lib/studium/yaml/curricula/master/master_biologie_molekulare_mikrobiologie_mikrobielle_oekologie_und_immunbiologie_066830.yml +78 -0
  831. data/lib/studium/yaml/curricula/master/master_biologische_chemie_066863.yml +66 -0
  832. data/lib/studium/yaml/curricula/master/master_dummy_curriculum.yml +197 -0
  833. data/lib/studium/yaml/curricula/master/master_genetik_und_entwicklungsbiologie_066877.yml +89 -0
  834. data/lib/studium/yaml/curricula/master/master_lmbt_066418.yml +112 -0
  835. data/lib/studium/yaml/curricula/master/master_molecular_biology_066865.yml +72 -0
  836. data/lib/studium/yaml/curricula/master/master_molekulare_biologie_066834.yml +151 -0
  837. data/lib/studium/yaml/curricula/master/master_pharmazie_066605.yml +176 -0
  838. data/lib/studium/yaml/curricula/master/master_technische_chemie_066490.yml +123 -0
  839. data/lib/studium/yaml/curricula/outdated/master_bioinformatics_and_molecular_biotechnology_including_aspects_from_molecular_medicine.yml +438 -0
  840. data/lib/studium/yaml/curricula/outdated/master_food_science_and_plant_biotechnology.yml +31 -0
  841. data/lib/studium/yaml/curricula.yml +562 -0
  842. data/lib/studium/yaml/daily_questions_solved/daily_questions_solved.yml +1849 -0
  843. data/lib/studium/yaml/default_delay.yml +4 -0
  844. data/lib/studium/yaml/default_encoding.yml +1 -0
  845. data/lib/studium/yaml/directory_to_the_exam_topics.yml +0 -0
  846. data/lib/studium/yaml/editor.yml +1 -0
  847. data/lib/studium/yaml/exams/next_exams_to_do.md +9 -0
  848. data/lib/studium/yaml/file_for_exam_questions.yml +1 -0
  849. data/lib/studium/yaml/german/README.md +2 -0
  850. data/lib/studium/yaml/german/german_to_english_month_names.yml +16 -0
  851. data/lib/studium/yaml/grouped_themes/grouped_themes.yml +258 -0
  852. data/lib/studium/yaml/holidays/holidays.yml +201 -0
  853. data/lib/studium/yaml/important_exams.yml +274 -0
  854. data/lib/studium/yaml/inscription_dates_of_universities.yml +60 -0
  855. data/lib/studium/yaml/lecture_aliases.yml +138 -0
  856. data/lib/studium/yaml/lecture_information/lecture_information.yml +63818 -0
  857. data/lib/studium/yaml/log_dir.yml +1 -0
  858. data/lib/studium/yaml/main_topic/main_topic.yml +11 -0
  859. data/lib/studium/yaml/max_stats.yml +256 -0
  860. data/lib/studium/yaml/meta_themes +1 -0
  861. data/lib/studium/yaml/mitbelegung/README.md +4 -0
  862. data/lib/studium/yaml/mitbelegung/mitbelegung.yml +21 -0
  863. data/lib/studium/yaml/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.yml +363 -0
  864. data/lib/studium/yaml/n_total_questions.yml +1 -0
  865. data/lib/studium/yaml/rename_konsole_tab.yml +1 -0
  866. data/lib/studium/yaml/semester_planner/README.md +4 -0
  867. data/lib/studium/yaml/semester_planner/semester_planner.yml +189 -0
  868. data/lib/studium/yaml/show_topic.yml +1 -0
  869. data/lib/studium/yaml/statistics/lecture_information.yml +1 -0
  870. data/lib/studium/yaml/statistics/max_stats.yml +239 -0
  871. data/lib/studium/yaml/statistics/statistics.yml +77 -0
  872. data/lib/studium/yaml/week/01_monday.yml +25 -0
  873. data/lib/studium/yaml/week/02_tuesday.yml +68 -0
  874. data/lib/studium/yaml/week/03_wednesday.yml +63 -0
  875. data/lib/studium/yaml/week/04_thursday.yml +20 -0
  876. data/lib/studium/yaml/week/05_friday.yml +31 -0
  877. data/lib/studium/yaml/week/06_saturday.yml +16 -0
  878. data/lib/studium/yaml/week/07_sunday.yml +0 -0
  879. data/lib/studium/yaml/week/README.md +10 -0
  880. data/lib/studium.rb +5 -0
  881. data/studium.gemspec +82 -0
  882. data/test/testing_colourized_question_and_answer.rb +18 -0
  883. data/test/testing_studium.rb +244 -0
  884. data/test/testing_studium_base_class.rb +31 -0
  885. data/test/testing_the_file_lecture_information.rb +18 -0
  886. data/test/testing_time_component.rb +29 -0
  887. metadata +1101 -0
@@ -0,0 +1,1889 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === Studium::GUI::Gtk::ExamQuestionWidget
6
+ #
7
+ # For SQL we could use this:
8
+ #
9
+ # result = `sqlite3 #{SQLITE_DATABASE_FILE} "SELECT * FROM #{current_exam_topic?} ORDER BY RANDOM() LIMIT 1;"`
10
+ # e result
11
+ #
12
+ # =========================================================================== #
13
+ # require 'studium/gui/gtk3/exam_question_widget/exam_question_widget.rb'
14
+ # Studium::GUI::Gtk::ExamQuestionWidget.run
15
+ # =========================================================================== #
16
+ require 'gtk_paradise/require_gtk3'
17
+
18
+ module Studium
19
+
20
+ module GUI
21
+
22
+ module Gtk
23
+
24
+ require 'gtk_paradise/requires/require_the_base_module.rb'
25
+
26
+ class ExamQuestionWidget < ::Gtk::BaseModuleBox # === Studium::GUI::Gtk::ExamQuestionWidget
27
+
28
+ require 'studium/project/project.rb'
29
+ require 'studium/constants/constants.rb'
30
+ require 'studium/exams/solved/solved.rb'
31
+ require 'studium/exams/exam_question/exam_question.rb'
32
+ require 'studium/toplevel_methods/available_topics.rb'
33
+ require 'studium/toplevel_methods/find_exam_topic_and_exam_title.rb'
34
+ require 'studium/toplevel_methods/return_question_answer_string_from_this_topic.rb'
35
+ require 'studium/toplevel_methods/return_n_questions_were_answered_for_this_topic.rb'
36
+ require 'studium/toplevel_methods/write_into_file_related_functionality.rb'
37
+ require 'studium/statistics/report_how_many_exam_questions_were_answered.rb'
38
+ require 'studium/exams/ask_exam_question/ask_exam_question.rb'
39
+
40
+ require 'studium/gui/shared_code/exam_question_widget/exam_question_widget_module.rb'
41
+ include Studium::GUI::ExamQuestionWidgetModule
42
+
43
+ begin
44
+ require 'roebe/toplevel_methods/rinstall2.rb'
45
+ rescue LoadError; end
46
+
47
+ # ========================================================================= #
48
+ # === WIDTH
49
+ # ========================================================================= #
50
+ WIDTH = '75%'
51
+
52
+ # ========================================================================= #
53
+ # === HEIGHT
54
+ # ========================================================================= #
55
+ HEIGHT = '85%'
56
+
57
+ # ========================================================================= #
58
+ # === USE_THIS_MARGIN
59
+ # ========================================================================= #
60
+ USE_THIS_MARGIN = 12
61
+
62
+ # ========================================================================= #
63
+ # === DEFAULT_DELAY
64
+ #
65
+ # This constant specifies how long to wait before the answer is
66
+ # revealed, if the user has set the checkbutton to "automatically
67
+ # answer the question".
68
+ # ========================================================================= #
69
+ DEFAULT_DELAY = '18.0'
70
+
71
+ # ========================================================================= #
72
+ # === USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC
73
+ #
74
+ # This constant can be used to specify the default exam topic to be
75
+ # used on startup of this application.
76
+ # ========================================================================= #
77
+ USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC =
78
+ 'virus' # stemcells' # chem1' #anatomy'
79
+
80
+ # ========================================================================= #
81
+ # === DEFAULT_PLACEHOLDER_TEXT
82
+ # ========================================================================= #
83
+ DEFAULT_PLACEHOLDER_TEXT =
84
+ 'You can input your answer to the exam question here.'
85
+
86
+ # ========================================================================= #
87
+ # === WORD_WRAP_AT_N_CHARACTERS
88
+ # ========================================================================= #
89
+ WORD_WRAP_AT_N_CHARACTERS = 78
90
+
91
+ # ========================================================================= #
92
+ # === SQLITE_DATABASE_FILE
93
+ #
94
+ # This is experimental - one day we may want to query from a sqlite
95
+ # database rather than flat files.
96
+ # ========================================================================= #
97
+ SQLITE_DATABASE_FILE = '/Depot/jjjj/exam_questions.db'
98
+
99
+ # ========================================================================= #
100
+ # === initialize
101
+ # ========================================================================= #
102
+ def initialize(
103
+ commandline_arguments = ARGV,
104
+ run_already = true
105
+ )
106
+ super(:vertical)
107
+ reset
108
+ set_commandline_arguments(
109
+ commandline_arguments
110
+ )
111
+ run if run_already
112
+ end
113
+
114
+ # ========================================================================= #
115
+ # === reset (reset tag)
116
+ # ========================================================================= #
117
+ def reset
118
+ reset_the_internal_variables
119
+ Studium.set_runmode :gui # Make it known that we use the gui-runmode in this case.
120
+ infer_the_namespace
121
+ # ======================================================================= #
122
+ # === @configuration
123
+ # ======================================================================= #
124
+ @configuration = [true, __dir__, namespace?]
125
+ # ======================================================================= #
126
+ # === @title
127
+ # ======================================================================= #
128
+ title_width_height_font(TITLE, WIDTH, HEIGHT, USE_THIS_FONT)
129
+ use_gtk_paradise_project_css_file
130
+ infer_the_size_automatically
131
+ # ======================================================================= #
132
+ # === @question_is
133
+ # ======================================================================= #
134
+ @question_is = ''.dup
135
+ # ======================================================================= #
136
+ # === @answer_is
137
+ # ======================================================================= #
138
+ @answer_is = ''.dup
139
+ # ======================================================================= #
140
+ # === @user_configuration
141
+ # ======================================================================= #
142
+ @user_configuration = {}
143
+ # ======================================================================= #
144
+ # === :available_exam_topics
145
+ #
146
+ # Keep a reference to the available exam topics.
147
+ # ======================================================================= #
148
+ @user_configuration[:available_exam_topics] = return_available_exam_topics.sort
149
+ # ======================================================================= #
150
+ # === :use_this_editor
151
+ #
152
+ # This may be :bluefish or :internal usually.
153
+ # ======================================================================= #
154
+ @user_configuration[:use_this_editor] = :bluefish
155
+ # ======================================================================= #
156
+ # === :show_ten_aliases
157
+ # ======================================================================= #
158
+ @user_configuration[:show_ten_aliases] = nil
159
+ # ======================================================================= #
160
+ # === :array_all_exam_questions
161
+ # ======================================================================= #
162
+ @user_configuration[:array_all_exam_questions] = []
163
+ # ======================================================================= #
164
+ # === @hash_dataset_of_all_lectures
165
+ # ======================================================================= #
166
+ @hash_dataset_of_all_lectures =
167
+ Studium::Statistics::ReportHowManyExamQuestionsWereAnswered.new { :be_quiet }.internal_dataset
168
+ # ======================================================================= #
169
+ # The next if-clause must come after @user_configuration has been
170
+ # defined.
171
+ # ======================================================================= #
172
+ if Object.const_defined?(:Roebe)
173
+ begin
174
+ require 'roebe/gui/gtk3/show_ten_aliases/show_ten_aliases.rb'
175
+ @user_configuration[:show_ten_aliases] = ::Roebe::GUI::Gtk::ShowTenAliases.new
176
+ rescue LoadError; end
177
+ end
178
+ handle_CSS
179
+ enable_all_key_combinations
180
+ upon_delete_event_quit_the_application
181
+ end
182
+
183
+ # ========================================================================= #
184
+ # === padding?
185
+ # ========================================================================= #
186
+ def padding?
187
+ 8
188
+ end
189
+
190
+ # ========================================================================= #
191
+ # === border_size?
192
+ # ========================================================================= #
193
+ def border_size?
194
+ 4
195
+ end
196
+
197
+ # ========================================================================= #
198
+ # === the_current_exam_question_is_now_solved (solved tag)
199
+ # ========================================================================= #
200
+ def the_current_exam_question_is_now_solved
201
+ _ = Studium::Exams::Solved.new { :do_not_run_yet }
202
+ _.set_commandline
203
+ _.run
204
+ if is_on_roebe? and Object.const_defined?(:Roebe)
205
+ rinstall2
206
+ end
207
+ end
208
+
209
+ # ========================================================================= #
210
+ # === create_text_view_for_the_answer
211
+ # ========================================================================= #
212
+ def create_text_view_for_the_answer
213
+ @text_view_for_the_answer = return_text_view_for_the_answer(@text_buffer_for_the_answer)
214
+ end
215
+
216
+ # ========================================================================= #
217
+ # === create_text_buffer_for_the_answer
218
+ # ========================================================================= #
219
+ def create_text_buffer_for_the_answer
220
+ @text_buffer_for_the_answer = gtk_text_buffer
221
+ end
222
+
223
+ # ========================================================================= #
224
+ # === text_view_containing_the_current_question?
225
+ # ========================================================================= #
226
+ def text_view_containing_the_current_question?
227
+ @text_view_for_the_question
228
+ end
229
+
230
+ # ========================================================================= #
231
+ # === add_the_status_icon
232
+ # ========================================================================= #
233
+ def add_the_status_icon
234
+ status_icon = return_status_icon
235
+ status_icon.favicon = Studium.project_base_directory?+
236
+ 'images/studies_favicon.png'
237
+ status_icon.hint = 'Exam-question widget: train your brain!'
238
+ menu = gtk_menu
239
+
240
+ button_hello_world = gtk_image_menu_item(stock: ::Gtk::Stock::FIND)
241
+ button_hello_world.signal_connect(:activate) {
242
+ e 'Hello world!'
243
+ }
244
+ menu << button_hello_world
245
+
246
+ quit_button = gtk_image_menu_item(stock: ::Gtk::Stock::QUIT)
247
+ quit_button.signal_connect(:activate) { ::Gtk.main_quit }
248
+ menu.append(quit_button)
249
+ menu.show_all
250
+
251
+ status_icon.signal_connect(:popup_menu) { |icon, button, time|
252
+ menu.popup(nil, nil, button, time)
253
+ }
254
+ end
255
+
256
+ # ========================================================================= #
257
+ # === return_button_solve_the_question
258
+ #
259
+ # .set_size_request() is not necessary as we use a separate method
260
+ # that controls the size of the widget at hand.
261
+ # ========================================================================= #
262
+ def return_button_solve_the_question
263
+ button_solve_the_question = bold_button(
264
+ mnemonic: '😁️ Mark the question as _solved ✓'
265
+ )
266
+ button_solve_the_question.lightblue
267
+ button_solve_the_question.hint = 'Use this button to <b>mark the '\
268
+ 'question as solved</b> (that is, correctly answered).'
269
+ # button_solve_the_question.set_size_request(78, 30)
270
+ return button_solve_the_question
271
+ end
272
+
273
+ # ========================================================================= #
274
+ # === return_available_exam_topics
275
+ # ========================================================================= #
276
+ def return_available_exam_topics
277
+ ::Studium.return_available_exam_topics
278
+ end
279
+
280
+ # ========================================================================= #
281
+ # === deselect_the_entry_containing_the_exam_topic
282
+ # ========================================================================= #
283
+ def deselect_the_entry_containing_the_exam_topic
284
+ @entry_holding_all_exam_topics.deselect
285
+ text_view_containing_the_current_question?.set_focus(true)
286
+ end
287
+
288
+ # ========================================================================= #
289
+ # === create_the_main_grid (grid tag)
290
+ # ========================================================================= #
291
+ def create_the_main_grid
292
+ # ======================================================================= #
293
+ # === @grid
294
+ # ======================================================================= #
295
+ @grid = default_grid
296
+ @grid.spacing1 = 8
297
+ @grid.spacing2 = 8
298
+ @grid.pad8px
299
+ end
300
+
301
+ # ========================================================================= #
302
+ # === do_jump_into_the_entry_containing_the_current_exam_topic
303
+ # ========================================================================= #
304
+ def do_jump_into_the_entry_containing_the_current_exam_topic
305
+ @entry_holding_all_exam_topics.do_focus_on_it
306
+ end
307
+
308
+ # ========================================================================= #
309
+ # === text_view_for_the_answer?
310
+ # ========================================================================= #
311
+ def text_view_for_the_answer?
312
+ @text_view_for_the_answer
313
+ end
314
+
315
+ # ========================================================================= #
316
+ # === return_text_view_for_the_question
317
+ # ========================================================================= #
318
+ def return_text_view_for_the_question(
319
+ text_buffer_for_the_question
320
+ )
321
+ text_view_for_the_question = gtk_text_view(text_buffer_for_the_question)
322
+ text_view_for_the_question.set_left_margin(USE_THIS_MARGIN)
323
+ text_view_for_the_question.set_right_margin(USE_THIS_MARGIN)
324
+ text_view_for_the_question.word_wrap
325
+ return text_view_for_the_question
326
+ end
327
+
328
+ # ========================================================================= #
329
+ # === show_ten_aliases?
330
+ # ========================================================================= #
331
+ def show_ten_aliases?
332
+ @user_configuration[:show_ten_aliases]
333
+ end
334
+
335
+ # ========================================================================= #
336
+ # === return_scrolled_window_for_the_text_view_for_the_question
337
+ # ========================================================================= #
338
+ def return_scrolled_window_for_the_text_view_for_the_question(text_view_for_the_question)
339
+ scrolled_window_containing_the_textarea1 = gtk_scrolled_window(
340
+ text_view_for_the_question
341
+ ) { :only_up_and_bottom }
342
+ scrolled_window_containing_the_textarea1.set_name('textview1') # Contains the question.
343
+ scrolled_window_containing_the_textarea1.set_size_request(1000, 150)
344
+ return scrolled_window_containing_the_textarea1
345
+ end
346
+
347
+ require 'studium/toplevel_methods/word_wrap.rb'
348
+ # ========================================================================= #
349
+ # === do_reveal_the_answer_after_timeout (revel tag)
350
+ #
351
+ # Note that the timeout will be in n ms (milliseconds).
352
+ # ========================================================================= #
353
+ def do_reveal_the_answer_after_timeout(
354
+ answer = answer_is?,
355
+ use_this_as_timeout = @entry_delay_to_use.text
356
+ )
357
+ if use_this_as_timeout.is_a? String
358
+ use_this_as_timeout = use_this_as_timeout.to_f * 1000
359
+ end
360
+ if answer
361
+ case answer
362
+ # ===================================================================== #
363
+ # === :default
364
+ # ===================================================================== #
365
+ when :default
366
+ answer = answer_is?
367
+ end
368
+ answer.gsub!(/\<.+?\>/,'')
369
+ #answer = ::Studium.word_wrap(answer, 78).to_s
370
+ if use_this_as_timeout > 0 and @checkbox_shall_we_reveal_the_answer.is_it_active?
371
+ # =================================================================== #
372
+ # This clause here is only ever entered when we have a delay. We
373
+ # have to check whether the main checkbox is active, because the
374
+ # user may have de-selected it in-between the delay time span.
375
+ # =================================================================== #
376
+ GLib::Timeout.add(use_this_as_timeout) {
377
+ @text_view_for_the_answer.set_text(answer)
378
+ false
379
+ }
380
+ else
381
+ @text_view_for_the_answer.set_text(answer)
382
+ end
383
+ end
384
+ end
385
+
386
+ # ======================================================================= #
387
+ # === set_exam_topic
388
+ # ======================================================================= #
389
+ def set_exam_topic(i)
390
+ i = i.to_s.downcase
391
+ @entry_holding_all_exam_topics.set_text(i)
392
+ end
393
+
394
+ # ========================================================================= #
395
+ # === return_button_open_exam_topic_file
396
+ # ========================================================================= #
397
+ def return_button_open_exam_topic_file
398
+ # ======================================================================= #
399
+ # This button will have the symbol for :open_file, an emoji - if
400
+ # emojis are used. Otherwise an image will be used instead.
401
+ # ======================================================================= #
402
+ if use_emoji?
403
+ _ = gtk_button(return_emoji(:open_box))
404
+ else
405
+ _ = gtk_button_with_this_image(image_open_file)
406
+ end
407
+ _.no_relief
408
+ _.lightblue
409
+ _.hint = 'Click this button to open the current exam-topic file.'
410
+ _.on_clicked {
411
+ do_open_the_current_exam_topic_file
412
+ }
413
+ return _
414
+ end
415
+
416
+ # ========================================================================= #
417
+ # === handle_CSS (CSS tag)
418
+ # ========================================================================= #
419
+ def handle_CSS
420
+ use_gtk_paradise_project_css_file
421
+ append_project_css_file
422
+ #apply_more_CSS_rules ''
423
+ apply_the_CSS_rules
424
+ end
425
+
426
+ # ========================================================================= #
427
+ # === return_checkbox_shall_we_reveal_the_answer
428
+ # ========================================================================= #
429
+ def return_checkbox_shall_we_reveal_the_answer
430
+ _ = gtk_checkbox(
431
+ "Automatically reveal the \nanswer after a delay"
432
+ )
433
+ _.set_font(SMALLEST_FONT)
434
+ # ======================================================================= #
435
+ # Next determine whether the checkbox is active, on startup, or whether
436
+ # it is not active when the GUI starts up.
437
+ # ======================================================================= #
438
+ _.mark_as_unchecked
439
+ _.hint = 'Deselect this if you do not want to automatically reveal '\
440
+ 'the answer. In that case you have to manually click on '\
441
+ 'the Answer button.'
442
+ _.on_toggled { |widget|
443
+ if _.active?
444
+ @entry_delay_to_use.grey_in
445
+ elsif not _.active?
446
+ @entry_delay_to_use.grey_out
447
+ end
448
+ }
449
+ if _.is_it_active?
450
+ @entry_delay_to_use.grey_in
451
+ else
452
+ @entry_delay_to_use.grey_out
453
+ end
454
+ return _
455
+ end
456
+
457
+ # ========================================================================= #
458
+ # === clear_reveal_the_answer
459
+ # ========================================================================= #
460
+ def clear_reveal_the_answer
461
+ @text_view_for_the_answer.set_text('')
462
+ end
463
+
464
+ # ========================================================================= #
465
+ # === do_clear_the_free_form_textarea
466
+ # ========================================================================= #
467
+ def do_clear_the_free_form_textarea
468
+ @textarea3.set_text('')
469
+ end
470
+
471
+ # ========================================================================= #
472
+ # === return_text_view_for_the_answer
473
+ # ========================================================================= #
474
+ def return_text_view_for_the_answer(
475
+ text_buffer_for_the_answer
476
+ )
477
+ _ = gtk_text_view(text_buffer_for_the_answer)
478
+ _.set_left_margin(USE_THIS_MARGIN)
479
+ _.set_right_margin(USE_THIS_MARGIN)
480
+ _.word_wrap
481
+ return _
482
+ end
483
+
484
+ # ========================================================================= #
485
+ # === return_frame_containing_the_label_exam_topic
486
+ # ========================================================================= #
487
+ def return_frame_containing_the_label_exam_topic
488
+ # ======================================================================= #
489
+ # Create the exam-topic label next, showing a watermelon emoji on the
490
+ # left-hand side. The watermelon emoji used to be 🍉️; but it was
491
+ # replaced with the electric light bulb emoji in January 2021, which
492
+ # is 💡️. Unfortunately this does not work on every system, so it
493
+ # was decided to replace this with an image that is determined by
494
+ # the icon theme at hand.
495
+ # ======================================================================= #
496
+ label_exam_topic = bold_label(' Exam topic')
497
+ # label_exam_topic.css_class('small_text_shadow')
498
+ label_emoji = right_arrow_emoji
499
+ label_emoji.set_size_request(30, 30)
500
+ label_emoji.align_right
501
+ tiny_hbox = gtk_hbox
502
+ tiny_hbox.minimal(label_exam_topic)
503
+ tiny_hbox.maximal(label_emoji)
504
+ tiny_hbox.minimal(text(' ')) # Just a "spacer".
505
+ frame_containing_the_label_exam_topic = gtk_frame(tiny_hbox)
506
+ frame_containing_the_label_exam_topic.modify_background(:normal, :oldlace)
507
+ frame_containing_the_label_exam_topic.css_class('bblack1')
508
+ label_exam_topic.hint = 'Denote <b>the current exam </b> topic '\
509
+ 'to the <b>right</b> of this text.'
510
+ return frame_containing_the_label_exam_topic
511
+ end
512
+
513
+ # ========================================================================= #
514
+ # === do_style_all_buttons_uniformly
515
+ # ========================================================================= #
516
+ def do_style_all_buttons_uniformly(
517
+ i = return_all_buttons
518
+ )
519
+ # ======================================================================= #
520
+ # Style all buttons uniformly next, via CSS.
521
+ # ======================================================================= #
522
+ i.each {|this_button|
523
+ # ===================================================================== #
524
+ # Use the same CSS rule for each button.
525
+ # ===================================================================== #
526
+ this_button.clear_background
527
+ this_button.css_class('bblack2')
528
+ this_button.set_size_request(75, 28)
529
+ this_button.set_name('button_hover_transition')
530
+ }
531
+ end
532
+
533
+ # ========================================================================= #
534
+ # === return_textarea_number_three
535
+ # ========================================================================= #
536
+ def return_textarea_number_three
537
+ # ======================================================================= #
538
+ # Next comes the textarea for "free typing", where the user can
539
+ # simply write whatever he wants to.
540
+ # ======================================================================= #
541
+ textarea = gtk_textarea
542
+ textarea.set_left_margin(USE_THIS_MARGIN)
543
+ textarea.set_right_margin(USE_THIS_MARGIN)
544
+ # ======================================================================= #
545
+ # The next code sets up a default placeholder text. Upon a focus-in-event
546
+ # that default placeholder text is removed.
547
+ # ======================================================================= #
548
+ textarea.buffer.set_placeholder_text(
549
+ DEFAULT_PLACEHOLDER_TEXT
550
+ )
551
+ textarea.buffer.sync_placeholder_text
552
+ textarea.focus_in_event {
553
+ if textarea.buffer.text? == DEFAULT_PLACEHOLDER_TEXT
554
+ textarea.buffer.clear # Remove that placeholder text in this case.
555
+ end
556
+ }
557
+ textarea.word_wrap
558
+ return textarea
559
+ end
560
+
561
+ # ========================================================================= #
562
+ # === return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
563
+ # ========================================================================= #
564
+ def return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
565
+ hbox_with_two_icons = gtk_hbox
566
+ first_eventbox = gtk_event_box(image_accessories_text_editor)
567
+ first_eventbox.on_clicked {
568
+ do_clear_the_free_form_textarea
569
+ }
570
+ hbox_with_two_icons.minimal(first_eventbox, 2)
571
+ text = gtk_label(
572
+ 'Below this text you can input your assumed '\
573
+ 'answer to the exam question at hand.'
574
+ )
575
+ text.left_align
576
+ text.make_selectable
577
+ text.set_font(:hack_18)
578
+ hbox_with_two_icons.maximal(text, 4)
579
+ event_box_for_image_accessories_text_editor = gtk_event_box(image_accessories_text_editor)
580
+ event_box_for_image_accessories_text_editor.hint = 'Click here to '\
581
+ 'empty the free-form textarea below this icon.'
582
+ event_box_for_image_accessories_text_editor.on_clicked {
583
+ do_clear_the_free_form_textarea
584
+ }
585
+ hbox_with_two_icons.minimal(event_box_for_image_accessories_text_editor, 2)
586
+ return hbox_with_two_icons
587
+ end
588
+
589
+ require 'studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb'
590
+ # ========================================================================= #
591
+ # === all_questions_have_been_answered_in_this_topic?
592
+ #
593
+ # This method has to determine how many questions have been answered
594
+ # in the current exam topic.
595
+ # ========================================================================= #
596
+ def all_questions_have_been_answered_in_this_topic?(
597
+ this_topic = current_exam_topic?
598
+ )
599
+ (Studium.return_n_percent_solved_from_this_topic(this_topic).to_i == 100)
600
+ end
601
+
602
+ # ========================================================================= #
603
+ # === use_emoji?
604
+ # ========================================================================= #
605
+ def use_emoji?
606
+ @prefer_emoji_or_images == :emoji
607
+ end
608
+
609
+ # ========================================================================= #
610
+ # === activate_the_third_textview
611
+ # ========================================================================= #
612
+ def activate_the_third_textview
613
+ @textarea3.do_focus_on_it
614
+ end
615
+
616
+ # ========================================================================= #
617
+ # === return_scrolled_window_containing_the_textarea3
618
+ # ========================================================================= #
619
+ def return_scrolled_window_containing_the_textarea3(textarea = @textarea3)
620
+ # ======================================================================= #
621
+ # === scrolled_window_containing_the_textarea3
622
+ #
623
+ # This is the scrolled-window containing the free-form text the user
624
+ # can type.
625
+ # ======================================================================= #
626
+ scrolled_window_containing_the_textarea3 = gtk_scrolled_window(textarea) { :only_top_to_bottom }
627
+ scrolled_window_containing_the_textarea3.set_name('textview3')
628
+ scrolled_window_containing_the_textarea3.css_class('pad4px')
629
+ scrolled_window_containing_the_textarea3.set_size_request(
630
+ 1000, 180
631
+ )
632
+ scrolled_window_containing_the_textarea3.do_show_the_scrollbars
633
+ scrolled_window_containing_the_textarea3.min_content_width = 100
634
+ scrolled_window_containing_the_textarea3.min_content_height = 150
635
+ # ======================================================================= #
636
+ # Next, enable select-all-on-click events:
637
+ # ======================================================================= #
638
+ scrolled_window_containing_the_textarea3.signal_connect(:event) {|widget, event|
639
+ case event.event_type.name.to_s
640
+ when 'GDK_BUTTON_PRESS'
641
+ # e 'The left mouse-button was clicked! Selecting everything next.'
642
+ # @text_view_for_simply_typing_anything.signal_emit(:select_all, event)
643
+ textarea.select_everything(event)
644
+ end
645
+ }
646
+ return scrolled_window_containing_the_textarea3
647
+ end
648
+
649
+ # ========================================================================= #
650
+ # === rinstall2
651
+ # ========================================================================= #
652
+ def rinstall2
653
+ Roebe.rinstall2(
654
+ use_this_directory: Studium.ruby_src_dir_at_home?+
655
+ 'studium/'
656
+ )
657
+ end; alias r2 rinstall2 # === r2
658
+
659
+ # ========================================================================= #
660
+ # === use_the_internal_editor?
661
+ # ========================================================================= #
662
+ def use_the_internal_editor?
663
+ @user_configuration[:use_this_editor] == :internal
664
+ end
665
+
666
+ # ========================================================================= #
667
+ # === return_n_answers_from_the_currently_selected_topic
668
+ # ========================================================================= #
669
+ def return_n_answers_from_the_currently_selected_topic(
670
+ i = exam_topic?
671
+ )
672
+ ::Studium.n_answers_available_in_this_topic(i)
673
+ end
674
+
675
+ # ========================================================================= #
676
+ # === main_font?
677
+ # ========================================================================= #
678
+ def main_font?
679
+ USE_THIS_FONT
680
+ end
681
+
682
+ # ========================================================================= #
683
+ # === entry_percentage?
684
+ # ========================================================================= #
685
+ def entry_percentage?
686
+ @entry_percentage
687
+ end
688
+
689
+ # ========================================================================= #
690
+ # === return_scrolled_window_containing_the_text_view_for_the_answer
691
+ # ========================================================================= #
692
+ def return_scrolled_window_containing_the_text_view_for_the_answer(
693
+ text_view_for_the_answer
694
+ )
695
+ @scrolled_window_containing_the_textarea2 = gtk_scrolled_window(
696
+ text_view_for_the_answer
697
+ ) { :only_up_and_bottom }
698
+ @scrolled_window_containing_the_textarea2.set_name('textview2') # Contains the answer.
699
+ @scrolled_window_containing_the_textarea2.set_size_request(1000, 150)
700
+ @scrolled_window_containing_the_textarea2.min_content_width = 100
701
+ @scrolled_window_containing_the_textarea2.min_content_height = 200
702
+ @scrolled_window_containing_the_textarea2.do_show_the_scrollbars
703
+ end
704
+
705
+ # ========================================================================= #
706
+ # === parse_for_URL
707
+ #
708
+ # This method can be used to return all URLs in a given text.
709
+ # ========================================================================= #
710
+ def parse_for_URL(
711
+ i = text_view_for_the_answer?.buffer.text
712
+ )
713
+ array = ::Studium.return_all_URLs_from(i)
714
+ if array.size > 0
715
+ first_entry = array.first
716
+ # ===================================================================== #
717
+ # We first have to assign it to the GUI part. Note that the "browser"
718
+ # is part of the control-panel since the rewrite in January 2021.
719
+ # ===================================================================== #
720
+ control_panel?.browser?.assign_this_text(first_entry)
721
+ ::Studium.open_this_remote_url(first_entry)
722
+ end
723
+ end
724
+
725
+ # ========================================================================= #
726
+ # === create_the_checkbox
727
+ #
728
+ # This has to be created after the entries are created.
729
+ # ========================================================================= #
730
+ def create_the_checkbox
731
+ # ======================================================================= #
732
+ # === @checkbox_shall_we_reveal_the_answer
733
+ # ======================================================================= #
734
+ @checkbox_shall_we_reveal_the_answer = return_checkbox_shall_we_reveal_the_answer
735
+ end
736
+
737
+ # ========================================================================= #
738
+ # === main_combo_box?
739
+ # ========================================================================= #
740
+ def main_combo_box?
741
+ @combo_box_available_exam_topics
742
+ end
743
+
744
+ # ========================================================================= #
745
+ # === return_eventbox_with_an_image_to_exit_the_application
746
+ # ========================================================================= #
747
+ def return_eventbox_with_an_image_to_exit_the_application
748
+ application_exit_image = return_this_image_based_on_the_default_icon_theme(
749
+ 'system-log-out-symbolic.symbolic'
750
+ ) # Or: :application_exit
751
+ _ = gtk_eventbox(application_exit_image)
752
+ _.hint = 'Click on this image to exit the program.'
753
+ _.on_clicked {
754
+ exit_application
755
+ }
756
+ return _
757
+ end
758
+
759
+ # ========================================================================= #
760
+ # === connect_skeleton (connect tag)
761
+ # ========================================================================= #
762
+ def connect_skeleton
763
+ abort_on_exception
764
+ # ======================================================================= #
765
+ # Add the status icon and style it a little bit as well.
766
+ # ======================================================================= #
767
+ add_the_status_icon
768
+ @grid.left(return_frame_containing_the_label_exam_topic)
769
+ mini_hbox = gtk_hbox
770
+ mini_hbox.minimal(@entry_holding_all_exam_topics, 2)
771
+ mini_hbox.minimal(@combo_box_available_exam_topics, 2)
772
+ mini_hbox.minimal(return_event_box_with_face_glasses, 2)
773
+ mini_hbox.rpack(return_eventbox_with_an_image_to_exit_the_application, 2)
774
+ @grid.right(mini_hbox)
775
+ @grid.left(@button_ask_the_exam_question)
776
+
777
+ # ======================================================================= #
778
+ # === @text_view_for_the_question
779
+ # ======================================================================= #
780
+ @text_buffer_for_the_question = gtk_text_buffer
781
+ @text_view_for_the_question = return_text_view_for_the_question(@text_buffer_for_the_question)
782
+ @scrolled_window_containing_the_textarea1 = return_scrolled_window_for_the_text_view_for_the_question(@text_view_for_the_question)
783
+
784
+ @grid.right(@scrolled_window_containing_the_textarea1)
785
+
786
+ @grid.left(@button_reveal_the_answer)
787
+ @scrolled_window_containing_the_textarea2 = return_scrolled_window_containing_the_text_view_for_the_answer(
788
+ @text_view_for_the_answer
789
+ )
790
+ @grid.right(@scrolled_window_containing_the_textarea2)
791
+
792
+ hbox_with_two_icons = return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
793
+ @grid.full_line(hbox_with_two_icons)
794
+
795
+ # ======================================================================= #
796
+ # === @textarea3
797
+ # ======================================================================= #
798
+ @textarea3 = return_textarea_number_three
799
+ @scrolled_window_containing_the_textarea3 = return_scrolled_window_containing_the_textarea3(@textarea3)
800
+ @grid.full_row(@scrolled_window_containing_the_textarea3)
801
+
802
+ lower_vbox = gtk_vbox
803
+ @hbox_containing_three_labels_and_three_entries = return_hbox_containing_three_labels_and_three_entries
804
+ middle_hbox = gtk_hbox
805
+ mini_hbox = gtk_hbox
806
+ # ======================================================================= #
807
+ # Add the checkbox for revealing the answer next:
808
+ # ======================================================================= #
809
+ mini_hbox.minimal(@checkbox_shall_we_reveal_the_answer, 2)
810
+ mini_hbox.minimal(@entry_delay_to_use, 2)
811
+ # ======================================================================= #
812
+ # The middle-hbox contains the other hboxes.
813
+ # ======================================================================= #
814
+ middle_hbox.minimal(mini_hbox, 1)
815
+ middle_hbox.minimal(@hbox_containing_three_labels_and_three_entries, 1)
816
+ middle_hbox.minimal(@button_use_random_entry_from_the_ten_aliases, 5)
817
+ middle_hbox.minimal(return_event_box_for_asking_a_random_exam_topic, 10)
818
+ lower_vbox.minimal(middle_hbox, 1)
819
+
820
+ small_hbox = gtk_hbox
821
+ small_hbox.minimal(@button_solve_the_question, 2)
822
+ small_hbox.minimal(return_button_open_exam_topic_file, 2)
823
+ small_hbox.minimal(return_wikipedia_entry, 2)
824
+ small_hbox.minimal(gtk_hseparator)
825
+
826
+ lower_vbox.minimal(small_hbox, 2)
827
+ lower_vbox.minimal(@label_n_questions_were_answered, 8)
828
+
829
+ draggable = draggable_up_and_down(
830
+ @grid,
831
+ lower_vbox
832
+ )
833
+ maximal(draggable)
834
+ end
835
+
836
+ # ========================================================================= #
837
+ # === do_clear_the_question_buffer
838
+ #
839
+ # Clear the question-buffer via this method.
840
+ # ========================================================================= #
841
+ def do_clear_the_question_buffer
842
+ @text_buffer_for_the_question.set_text('')
843
+ end
844
+
845
+ require 'studium/toplevel_methods/n_questions_available.rb'
846
+ # ========================================================================= #
847
+ # === return_n_questions_from_the_currently_selected_topic
848
+ # ========================================================================= #
849
+ def return_n_questions_from_the_currently_selected_topic(
850
+ i = exam_topic?
851
+ )
852
+ ::Studium.n_questions_available_in_this_topic(i)
853
+ end
854
+
855
+ # ========================================================================= #
856
+ # === reveal_the_answer_to_the_exam_question
857
+ # ========================================================================= #
858
+ def reveal_the_answer_to_the_exam_question
859
+ do_reveal_the_answer_after_timeout(:default, 0)
860
+ end
861
+
862
+ # ========================================================================= #
863
+ # === create_the_ask_the_exam_question_button
864
+ # ========================================================================= #
865
+ def create_the_ask_the_exam_question_button
866
+ # ======================================================================= #
867
+ # === @button_ask_the_exam_question
868
+ # ======================================================================= #
869
+ @button_ask_the_exam_question = return_button_ask_the_exam_question(use_emoji?)
870
+ end
871
+
872
+ # ========================================================================= #
873
+ # === return_button_ask_the_exam_question (ask tag)
874
+ # ========================================================================= #
875
+ def return_button_ask_the_exam_question(
876
+ use_emoji = false
877
+ )
878
+ # ======================================================================= #
879
+ # Add the ask-exam-question button next. Note that its click-event
880
+ # is handled separately via a method call.
881
+ #
882
+ # The question mark emoji is Unicode Character "❓" (U+2753).
883
+ # ======================================================================= #
884
+ if use_emoji?
885
+ button_ask_the_exam_question = gtk_bold_button(mnemonic: 'Ask a _Question ❓')
886
+ else
887
+ button_ask_the_exam_question = gtk_bold_button(mnemonic: 'Ask a _Question')
888
+ end
889
+ button_ask_the_exam_question.set_size_request(75, 28)
890
+ button_ask_the_exam_question.clear_background
891
+ button_ask_the_exam_question.pad2px
892
+ button_ask_the_exam_question.hint =
893
+ 'Click on this button to ask an exam-question. '\
894
+ '(Or, use alt+q as shortcut)'
895
+ return button_ask_the_exam_question
896
+ end
897
+
898
+ # ========================================================================= #
899
+ # === button_ask_the_exam_question?
900
+ # ========================================================================= #
901
+ def button_ask_the_exam_question?
902
+ @button_ask_the_exam_question
903
+ end; alias question_button? button_ask_the_exam_question? # === question_button?
904
+ alias button_ask_the_question? button_ask_the_exam_question? # === button_ask_the_question?
905
+
906
+ # ========================================================================= #
907
+ # === do_handle_the_click_event_for_the_ask_question_button (clicked tag)
908
+ #
909
+ # This method requires the Studium.write_what_into() method.
910
+ # ========================================================================= #
911
+ def do_handle_the_click_event_for_the_ask_question_button
912
+ # ======================================================================= #
913
+ # Determine what happens next when the ask-question button is clicked.
914
+ # ======================================================================= #
915
+ button_ask_the_question?.on_clicked {
916
+ the_button_ask_the_question_was_clicked
917
+ }
918
+ end
919
+
920
+ # ========================================================================= #
921
+ # === update_the_label_n_questions_were_answered
922
+ # ========================================================================= #
923
+ def update_the_label_n_questions_were_answered(
924
+ i = @label_n_questions_were_answered
925
+ )
926
+ i.set_text(
927
+ return_string_how_many_exam_questions_are_already_answered
928
+ )
929
+ end
930
+
931
+ # ========================================================================= #
932
+ # === create_the_buttons (buttons tag, button tag)
933
+ # ========================================================================= #
934
+ def create_the_buttons
935
+ create_the_ask_the_exam_question_button
936
+ create_the_button_use_random_entry_from_the_ten_aliases
937
+ create_the_reveal_button
938
+ # ======================================================================= #
939
+ # === @button_solve_the_question
940
+ # ======================================================================= #
941
+ @button_solve_the_question = return_button_solve_the_question
942
+ @button_solve_the_question.on_clicked {
943
+ the_current_exam_question_is_now_solved
944
+ update_three_important_widgets
945
+ do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
946
+ @entry_percentage, current_exam_topic?
947
+ )
948
+ }
949
+ end
950
+
951
+ # ========================================================================= #
952
+ # === return_entry_percentage
953
+ # ========================================================================= #
954
+ def return_entry_percentage
955
+ _ = entry('')
956
+ _.hint = "This denotes how many questions have already\n"\
957
+ "been answered successfully, <b>in percent</b>.\n"\
958
+ "Note that this requires a specific exam topic to "\
959
+ "have been set, so no percentage value may be "\
960
+ "shown initially.\nSimply assign to an exam topic "\
961
+ "and it should work fine."
962
+ _.do_center
963
+ _.disable_user_input
964
+ _.set_name('BG_bisque')
965
+ _.bblack1
966
+ return _
967
+ end
968
+
969
+ # ========================================================================= #
970
+ # === create_the_reveal_button
971
+ # ========================================================================= #
972
+ def create_the_reveal_button
973
+ # ======================================================================= #
974
+ # === The reveal-button is created next, also known as the
975
+ # "answer button". (answer tag)
976
+ # The mnemonic-key is set to "A".
977
+ # ======================================================================= #
978
+ @button_reveal_the_answer = gtk_bold_button(
979
+ mnemonic: 'Reveal the _Answer' # This was the old emoji: ❗
980
+ )
981
+ @button_reveal_the_answer.set_size_request(78, 30)
982
+ @button_reveal_the_answer.lightblue
983
+ @button_reveal_the_answer.on_clicked {
984
+ if all_questions_have_been_answered_in_this_topic?
985
+ notify_the_user_that_all_questions_have_been_answered_in_this_topic(
986
+ current_topic?,
987
+ @button_reveal_the_answer
988
+ )
989
+ else
990
+ do_reveal_the_answer_after_timeout(answer_is?, 0)
991
+ end
992
+ }
993
+ @button_reveal_the_answer.hint = 'Click on this button in order to '\
994
+ 'reveal the answer to the current exam question at hand.'
995
+ end
996
+
997
+ # ========================================================================= #
998
+ # === update_three_important_widgets
999
+ # ========================================================================= #
1000
+ def update_three_important_widgets
1001
+ update_the_label_n_questions_were_answered
1002
+ update_the_entry_n_unanswered_questions
1003
+ update_the_percentage_entry
1004
+ end
1005
+
1006
+ require 'studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb'
1007
+ # ========================================================================= #
1008
+ # === do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value
1009
+ # ========================================================================= #
1010
+ def do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
1011
+ entry_percentage = entry_percentage?,
1012
+ use_this_exam_topic = current_exam_topic?.to_s
1013
+ )
1014
+ percentage_value = Studium.n_percent_questions_answered_of_this_topic?(
1015
+ use_this_exam_topic.downcase
1016
+ )
1017
+ if percentage_value == false
1018
+ percentage_value = -1
1019
+ end
1020
+ percentage_value = percentage_value.to_s.to_f.round(1)
1021
+ percentage_value = percentage_value.to_s.dup
1022
+ percentage_value << '%' unless percentage_value.end_with? '%'
1023
+ entry_percentage.set_text(percentage_value) # And sync it onto the proper entry.
1024
+ end; alias update_the_percentage_entry do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value # === update_the_percentage_entry
1025
+
1026
+ # ========================================================================= #
1027
+ # === enable_alt_y_key_combination
1028
+ # ========================================================================= #
1029
+ def enable_alt_y_key_combination
1030
+ # ======================================================================= #
1031
+ # Add alt+y key combination, to assign a new exam topic:
1032
+ # ======================================================================= #
1033
+ use_this_key = Gdk::Keyval::KEY_Y
1034
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+y
1035
+ do_assign_a_new_exam_topic
1036
+ }
1037
+ end
1038
+
1039
+ # ========================================================================= #
1040
+ # === enable_alt_w_key_combination
1041
+ #
1042
+ # This method will specifically enable the "alt+w" shortcut.
1043
+ # ========================================================================= #
1044
+ def enable_alt_w_key_combination
1045
+ # ======================================================================= #
1046
+ # Add alt+w key combination, to open the current exam topic file:
1047
+ # ======================================================================= #
1048
+ use_this_key = Gdk::Keyval::KEY_W
1049
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+w
1050
+ do_open_the_current_exam_topic_file
1051
+ }
1052
+ end
1053
+
1054
+ # ========================================================================= #
1055
+ # === enable_alt_1_key_combination
1056
+ # ========================================================================= #
1057
+ def enable_alt_1_key_combination
1058
+ # ======================================================================= #
1059
+ # Add alt+1 key combination:
1060
+ # ======================================================================= #
1061
+ use_this_key = Gdk::Keyval::KEY_1
1062
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+1
1063
+ entry_ask_questions?.set_focus(true)
1064
+ }
1065
+ end
1066
+
1067
+ # ========================================================================= #
1068
+ # === Studium::GUI::Gtk::ExamQuestionWidget.run
1069
+ # ========================================================================= #
1070
+ def self.run(
1071
+ i = ARGV
1072
+ )
1073
+ require 'gtk_paradise/app/app.rb'
1074
+ _ = ::Studium::GUI::Gtk::ExamQuestionWidget.new(i)
1075
+ r = ::Gtk.run
1076
+ r << _
1077
+ r.add_context_menu_with_the_default_accel_group
1078
+ r.on_button_press_event { |widget, event|
1079
+ if ::Gtk.right_mouse_click?(event) # right mouse click event.
1080
+ _.context_menu?.popup_based_on_this_event(event)
1081
+ end
1082
+ }
1083
+ r.automatic_size_then_automatic_title
1084
+ r.top_left_then_run
1085
+ end
1086
+
1087
+ # ========================================================================= #
1088
+ # === Studium::GUI::Gtk::AskExamQuestion.gtk_accel_group
1089
+ # ========================================================================= #
1090
+ def self.gtk_accel_group
1091
+ ::Gtk::AccelGroup.new
1092
+ end
1093
+
1094
+ # ========================================================================= #
1095
+ # === popup_pick_a_new_font
1096
+ # ========================================================================= #
1097
+ def popup_pick_a_new_font
1098
+ _ = gtk_hbox
1099
+ _.minimal(text(' → '))
1100
+ file_chooser_widget = gtk_button('Choose font here')
1101
+ file_chooser_widget.set_size_request(1200, 960)
1102
+ file_chooser_widget.css_class('bblack2')
1103
+ file_chooser_widget.set_size_request(500, 300)
1104
+ file_chooser_widget.disallow_resizing
1105
+ _.minimal(file_chooser_widget)
1106
+ file_chooser_widget.on_click {
1107
+ result = gtk_font_chooser_dialog
1108
+ set_use_this_font(::Gtk.main_file?)
1109
+ result.destroy
1110
+ }
1111
+ # ======================================================================= #
1112
+ # Next create the popup for the font-choosing.
1113
+ # ======================================================================= #
1114
+ popup_widget = popup_over_this_widget(
1115
+ text_view_for_the_question?,
1116
+ '',
1117
+ _
1118
+ )
1119
+ # popup_widget.no_arrow # ← This will only work on gtk4, I think.
1120
+ popup_widget.popup
1121
+ end
1122
+
1123
+ # ========================================================================= #
1124
+ # === text_view_for_the_question?
1125
+ # ========================================================================= #
1126
+ def text_view_for_the_question?
1127
+ @text_view_for_the_question
1128
+ end
1129
+
1130
+ # ========================================================================= #
1131
+ # === top_textbuffer?
1132
+ # ========================================================================= #
1133
+ def top_textbuffer?
1134
+ @text_view_for_the_question.buffer
1135
+ end
1136
+
1137
+ # ========================================================================= #
1138
+ # === current_exam_topic?
1139
+ # ========================================================================= #
1140
+ def current_exam_topic?
1141
+ @entry_holding_all_exam_topics.text?.strip
1142
+ end; alias main_exam_topic? current_exam_topic? # === main_exam_topic?
1143
+ alias exam_topic? current_exam_topic? # === exam_topic?
1144
+ alias current_topic? current_exam_topic? # === current_topic?
1145
+
1146
+ # ========================================================================= #
1147
+ # === the_button_ask_the_question_was_clicked
1148
+ # ========================================================================= #
1149
+ def the_button_ask_the_question_was_clicked
1150
+ # ======================================================================= #
1151
+ # (1) First, clear the old question-buffer, just in case.
1152
+ # ======================================================================= #
1153
+ do_clear_the_question_buffer
1154
+ # ======================================================================= #
1155
+ # (2) Query the exam-topic that is part of the combo box
1156
+ # ======================================================================= #
1157
+ _ = @combo_box_available_exam_topics.text?.tr(' ','_').downcase
1158
+ if _.empty?
1159
+ bold_popover_message = bold_label(
1160
+ 'You have to provide an exam-topic - see the text above.'
1161
+ )
1162
+ popover_message(
1163
+ bold_popover_message,
1164
+ button_ask_the_exam_question?
1165
+ ).popup
1166
+ end
1167
+ # ======================================================================= #
1168
+ # (3) Check whether there is no exam-topic selected. We have to be
1169
+ # careful here, as an infinite loop may result.
1170
+ # ======================================================================= #
1171
+ unless entry_ask_questions_from_this_topic?.empty?
1172
+ # This clause is entered when the user has a gtk-entry point.
1173
+ _ = entry_ask_questions_from_this_topic?.text.to_s
1174
+ use_this_index = ::Studium.find_corresponding_exam_title(_)
1175
+ use_this_topic = available_exam_topics?.index(use_this_index)
1176
+ # ===================================================================== #
1177
+ # Next be careful - we don't want an infinite loop:
1178
+ # ===================================================================== #
1179
+ if use_this_topic
1180
+ #@combo_box_available_exam_topics.set_active(use_this_topic)
1181
+ #entry_ask_questions_from_this_topic?.set_text(_) # Need to sync it back again.
1182
+ do_updated_the_entries_n_answered_and_n_unanswered
1183
+ end
1184
+ end
1185
+ if @entry_percentage.text.to_f == 100.0
1186
+ # ===================================================================== #
1187
+ # Handle the case where the exam-topic at hand has been answered
1188
+ # completely.
1189
+ # ===================================================================== #
1190
+ bold_popover_message = gtk_bold_label(
1191
+ "All questions have been answered for the topic "\
1192
+ "#{exam_topic?}.\n\n Please choose another exam topic.\n"
1193
+ )
1194
+ popover_message(
1195
+ bold_popover_message,
1196
+ @button_ask_the_exam_question
1197
+ ).popup
1198
+ else
1199
+ # ===================================================================== #
1200
+ # Check whether the exam-topic is registered:
1201
+ # ===================================================================== #
1202
+ if ::Studium.is_this_exam_topic_available?(_)
1203
+ @question_answer = Studium.ask_question(_) { :do_not_run_yet }
1204
+ @question_answer.initial_steps
1205
+ line = @question_answer.line?.to_s.tr("\n", ' ').rstrip
1206
+ array_all_exam_questions? << line
1207
+ # =================================================================== #
1208
+ # Store it as well.
1209
+ # =================================================================== #
1210
+ into = ::Studium.file_last_question_asked?
1211
+ Studium.write_what_into(line, into)
1212
+ index = @question_answer.split_position?
1213
+ question = line[0 .. index]
1214
+ question.tr!("\n", ' ')
1215
+ question.rstrip!
1216
+ if line
1217
+ @answer_is = line[(index+1) .. -1].strip.dup
1218
+ @answer_is = ::Gtk.replace_all_URL_entries_in_this_string(@answer_is)
1219
+ @answer_is.lstrip!
1220
+ if @answer_is.start_with? 'A: '
1221
+ @answer_is.sub!(/A: /,'')
1222
+ end
1223
+ # ================================================================= #
1224
+ # Replace all "(2) foo" entries with "(2) foo\n" entries.
1225
+ # ================================================================= #
1226
+ require 'studium/toplevel_methods/misc.rb'
1227
+ @answer_is = ::Studium.add_newlines_to_numbered_exam_question(@answer_is)
1228
+ end
1229
+ # =================================================================== #
1230
+ # Remove <one> and similar tags.
1231
+ # =================================================================== #
1232
+ question.gsub!(/\<.+?\>/,'')
1233
+ # @question = ::Studium.word_wrap(question, WORD_WRAP_AT_N_CHARACTERS).to_s
1234
+ @question = question.to_s.dup
1235
+ if @question.start_with?('- ')
1236
+ @question[0,2] = ''
1237
+ end
1238
+ # =================================================================== #
1239
+ # Replace all URL entries with <a href> entries next:
1240
+ # =================================================================== #
1241
+ @question = ::Gtk.replace_all_URL_entries_in_this_string(@question)
1242
+ @text_buffer_for_the_question.set_text(@question)
1243
+ @text_view_for_the_answer.set_text('') # ← This is needed to clear old entries.
1244
+ if @checkbox_shall_we_reveal_the_answer.active?
1245
+ do_reveal_the_answer_after_timeout(answer_is?)
1246
+ end
1247
+ # =================================================================== #
1248
+ # Reveal the exam-file onto the gtk-based editor as well.
1249
+ # Unfortunately this has a bug, in February 2021 - x11
1250
+ # crashes. I may have to re-evaluate this at a later time
1251
+ # to determine WHY it crashes...
1252
+ # =================================================================== #
1253
+ # dataset = File.read(
1254
+ # ::Studium.directory_containing_the_exam_topics?+
1255
+ # ::Studium.find_corresponding_exam_topic(
1256
+ # current_exam_topic?
1257
+ # )
1258
+ # )
1259
+ # @gtk_editor.update_the_main_buffer(dataset)
1260
+ else # else we can notify the user that this exam-topic is not registered.
1261
+ popover = return_popover(
1262
+ ' <b>⚠️</b> The exam topic `<b>'+
1263
+ entry_ask_questions_from_this_topic?.text.to_s+
1264
+ '</b>` could <b>not</b> be found. <b>⚠️</b>',
1265
+ question_button?
1266
+ )
1267
+ popover.show_all
1268
+ popover.popup # Display it at once.
1269
+ end
1270
+ end
1271
+ end; alias do_ask_a_new_question the_button_ask_the_question_was_clicked # === do_ask_a_new_question
1272
+ alias do_ask_an_exam_question the_button_ask_the_question_was_clicked # === do_ask_an_exam_question
1273
+ alias do_ask_the_exam_question the_button_ask_the_question_was_clicked # === do_ask_the_exam_question
1274
+ alias ask_an_exam_question the_button_ask_the_question_was_clicked # === ask_an_exam_question
1275
+ alias do_all_the_internal_actions_associated_with_the_button_ask_the_question_having_been_clicked the_button_ask_the_question_was_clicked # === do_all_the_internal_actions_associated_with_the_button_ask_the_question_having_been_clicked
1276
+
1277
+ # ========================================================================= #
1278
+ # === handle_the_combo_box_available_exam_topics_on_changed_event
1279
+ # ========================================================================= #
1280
+ def handle_the_combo_box_available_exam_topics_on_changed_event(
1281
+ combo_box = @combo_box_available_exam_topics
1282
+ )
1283
+ # ======================================================================= #
1284
+ # The event where the combo-box is changed is handled next.
1285
+ # ======================================================================= #
1286
+ combo_box.on_changed {
1287
+ entry_ask_questions_from_this_topic?.set_text(
1288
+ combo_box.active_text.to_s.downcase.tr(' ','_')
1289
+ )
1290
+ # ===================================================================== #
1291
+ # Get a reference to the current exam topic.
1292
+ # ===================================================================== #
1293
+ current_exam_topic = combo_box.active_text.to_s.strip.dup
1294
+ current_exam_topic.strip! if current_exam_topic.end_with? '_'
1295
+ do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
1296
+ @entry_percentage, current_exam_topic
1297
+ )
1298
+ @entry_containing_n_questions.set_text(
1299
+ return_n_questions_from_the_currently_selected_topic(current_exam_topic).to_s
1300
+ )
1301
+ do_update_the_entry_n_answered(current_exam_topic)
1302
+ do_ask_a_new_question
1303
+ }
1304
+ end
1305
+
1306
+ # ========================================================================= #
1307
+ # === create_the_combobox
1308
+ # ========================================================================= #
1309
+ def create_the_combobox
1310
+ # ======================================================================= #
1311
+ # Next, create the combo-box that contains all exam-topics. It will be
1312
+ # a bit truncated, largely for display-reasons rather than any other
1313
+ # reason.
1314
+ # ======================================================================= #
1315
+ @combo_box_available_exam_topics = return_combo_box_available_exam_topics
1316
+ end
1317
+
1318
+ # ========================================================================= #
1319
+ # === return_wikipedia_entry
1320
+ #
1321
+ # This method will return the widget that, upon user-mouse-button-click
1322
+ # event, will open the corresponding wikipedia entry. This defaults
1323
+ # to the german wikipedia entry right now; if others want to change
1324
+ # the default then this could be changed easily.
1325
+ # ========================================================================= #
1326
+ def return_wikipedia_entry
1327
+ begin
1328
+ require 'roebe/classes/wikipedia.rb'
1329
+ rescue LoadError; end
1330
+
1331
+ hbox = gtk_hbox
1332
+ wikipedia_entry = gtk_entry
1333
+ wikipedia_entry.clear_background
1334
+ wikipedia_entry.bblack2
1335
+ wikipedia_entry.center
1336
+ wikipedia_entry.css_class('pad5px')
1337
+ wikipedia_entry.lightgreen_background
1338
+ wikipedia_entry.width_height(720, 32)
1339
+ wikipedia_entry.hint =
1340
+ 'Click the "enter" key to open the assorted keyword in the '\
1341
+ 'german-wikipedia. Simply replace <b>de</b> with <b>en</b> in '\
1342
+ 'the URL to have the english wikipedia.'
1343
+ wikipedia_entry.on_enter {
1344
+ if Object.const_defined?(:Roebe) and
1345
+ Roebe.const_defined?(:Wikipedia)
1346
+ Roebe::Wikipedia.new(wikipedia_entry.text?)
1347
+ else
1348
+ e 'You need to install the roebe gem for this functionality.'
1349
+ end
1350
+ }
1351
+ hbox.minimal(wikipedia_entry, 1)
1352
+ return hbox
1353
+ end
1354
+
1355
+ # ========================================================================= #
1356
+ # === create_skeleton (create tag)
1357
+ # ========================================================================= #
1358
+ def create_skeleton
1359
+ create_text_buffer_for_the_answer
1360
+ create_text_view_for_the_answer
1361
+ create_the_buttons
1362
+ create_the_labels
1363
+ create_the_entries
1364
+ create_the_checkbox # This must come after the entries.
1365
+ create_the_combobox
1366
+ create_the_main_grid
1367
+ create_the_context_menu
1368
+ end
1369
+
1370
+ # ========================================================================= #
1371
+ # === context_menu?
1372
+ # ========================================================================= #
1373
+ def context_menu?
1374
+ @context_menu
1375
+ end
1376
+
1377
+ # ========================================================================= #
1378
+ # === create_the_context_menu
1379
+ #
1380
+ # This is the context-menu which will appear on a right-mouse
1381
+ # click event.
1382
+ # ========================================================================= #
1383
+ def create_the_context_menu
1384
+ # ======================================================================= #
1385
+ # === @context_menu
1386
+ # ======================================================================= #
1387
+ @context_menu = create_context_menu(self) {{
1388
+ numbered_actions: {
1389
+ 'Ask an exam question': :ask_an_exam_question,
1390
+ 'Reveal the answer to the exam question': :reveal_the_answer_to_the_exam_question,
1391
+ 'Mark the exam question as solved': :mark_the_exam_question_as_solved,
1392
+ 'Pick a new font (show the widget)': :popup_pick_a_new_font,
1393
+ 'Debug': :debug
1394
+ #'Change the font in use': :do_interactively_change_the_font,
1395
+ }
1396
+ }}
1397
+ @context_menu.make_bold
1398
+ @context_menu.set_font(:hack_18)
1399
+ end
1400
+
1401
+ # ========================================================================= #
1402
+ # === enable_all_key_combinations
1403
+ # ========================================================================= #
1404
+ def enable_all_key_combinations
1405
+ # ======================================================================= #
1406
+ # === @accel_group
1407
+ # ======================================================================= #
1408
+ @accel_group = create_and_add_gtk_accel_group
1409
+ enable_alt_w_key_combination
1410
+ enable_alt_y_key_combination
1411
+ enable_alt_1_key_combination
1412
+ end
1413
+
1414
+ # ========================================================================= #
1415
+ # === create_the_entries (entries tag, entry tag)
1416
+ # ========================================================================= #
1417
+ def create_the_entries
1418
+ # ======================================================================= #
1419
+ # === The entry keeping track as to how many answers have been
1420
+ # given for that particular exam-topic.
1421
+ # ======================================================================= #
1422
+ @entry_containing_n_answers = gtk_entry('')
1423
+ @entry_containing_n_answers.center
1424
+ @entry_containing_n_answers.set_font(:hack_15)
1425
+ @entry_containing_n_answers.bblack1
1426
+ # ======================================================================= #
1427
+ # === @entry_containing_n_questions
1428
+ #
1429
+ # Next, the entry containing the questions
1430
+ # ======================================================================= #
1431
+ @entry_containing_n_questions = entry('')
1432
+ @entry_containing_n_questions.center
1433
+ @entry_containing_n_questions.set_font(:hack_15)
1434
+ @entry_containing_n_questions.bblack1
1435
+ # ======================================================================= #
1436
+ # === @entry_containing_n_unanswered_questions
1437
+ # ======================================================================= #
1438
+ @entry_containing_n_unanswered_questions = entry('')
1439
+ @entry_containing_n_unanswered_questions.center
1440
+ @entry_containing_n_unanswered_questions.set_font(:hack_15)
1441
+ @entry_containing_n_unanswered_questions.bblack1
1442
+ # ======================================================================= #
1443
+ # === The entry holding all exam topics.
1444
+ #
1445
+ # This is the entry that the user can modify at his or her own
1446
+ # discretion. It is the most important entry, among the entries
1447
+ # used in this GUI application.
1448
+ #
1449
+ # This entry is positioned very close on top, on the left hand side.
1450
+ # The user can thus simply manipulate it by clicking on it.
1451
+ #
1452
+ # Another entry may depend on this entry, so it should come early
1453
+ # in this method.
1454
+ # ======================================================================= #
1455
+ @entry_holding_all_exam_topics = gtk_entry(
1456
+ USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC
1457
+ )
1458
+ # The next line of code was disabled as of September 2021.
1459
+ # @entry_holding_all_exam_topics.on_click_select_everything
1460
+ @entry_holding_all_exam_topics.set_font(SMALLER_FONT)
1461
+ @entry_holding_all_exam_topics.bblack1
1462
+ @entry_holding_all_exam_topics.very_light_yellowish_background
1463
+ enhanced_gtk_entry = gtk_entry_completion
1464
+ enhanced_gtk_entry.populate_with_this_array(
1465
+ ::Studium.return_all_exam_topics
1466
+ )
1467
+ @entry_holding_all_exam_topics.completion = enhanced_gtk_entry
1468
+ # ======================================================================= #
1469
+ # We need this entry to be fairly wide, hence the following method call.
1470
+ # ======================================================================= #
1471
+ @entry_holding_all_exam_topics.set_size_request(500, 40)
1472
+ @entry_holding_all_exam_topics.set_hexpand(false)
1473
+ @entry_holding_all_exam_topics.set_vexpand(false)
1474
+ # ======================================================================= #
1475
+ # Allow for scroll-events.
1476
+ # ======================================================================= #
1477
+ @entry_holding_all_exam_topics.enable_scroll_events
1478
+ @entry_holding_all_exam_topics.on_scroll_event {|widget, event|
1479
+ # ===================================================================== #
1480
+ # For now this simply sets a new, random topic.
1481
+ # ===================================================================== #
1482
+ if scroll_up?(event)
1483
+ set_exam_topic(
1484
+ available_exam_topics?.sample.downcase
1485
+ )
1486
+ sync_entry_holding_all_exam_topics_onto_the_combo_box # Sync towards the combo-box.
1487
+ elsif scroll_down?(event)
1488
+ set_exam_topic(
1489
+ available_exam_topics?.sample.downcase
1490
+ )
1491
+ sync_entry_holding_all_exam_topics_onto_the_combo_box # Sync towards the combo-box.
1492
+ end
1493
+ }
1494
+ # ======================================================================= #
1495
+ # Respond to the enter-key pressed next.
1496
+ # ======================================================================= #
1497
+ @entry_holding_all_exam_topics.on_enter_key_pressed { |widget, event|
1498
+ old_text = @entry_holding_all_exam_topics.text?
1499
+ new_possible_text = Studium.expand_this_exam_topic(old_text)
1500
+ unless old_text == new_possible_text
1501
+ @entry_holding_all_exam_topics.set_text(new_possible_text)
1502
+ end
1503
+ do_update_the_entry_n_questions
1504
+ question_button?.signal_emit(:clicked)
1505
+ sync_entry_holding_all_exam_topics_onto_the_main_combo_box
1506
+ }
1507
+ # ======================================================================= #
1508
+ # === @entry_delay_to_use
1509
+ #
1510
+ # Next create the delay-entry that keeps track how many seconds to wait,
1511
+ # before revealing the answer (IF the user has decided to make use of
1512
+ # that functionality).
1513
+ # ======================================================================= #
1514
+ @entry_delay_to_use = gtk_entry(DEFAULT_DELAY)
1515
+ @entry_delay_to_use.center
1516
+ @entry_delay_to_use.hint = 'Provide the delay here, as <b>n seconds</b>. '\
1517
+ 'This will only work when the checkbox on the left-hand side is active.'
1518
+ @entry_delay_to_use.set_size_request(45, 20)
1519
+ @entry_delay_to_use.bblack1
1520
+ # ======================================================================= #
1521
+ # === Percentage entry
1522
+ #
1523
+ # This is the percentage-entry, situated right next to a combo-box
1524
+ # entry.
1525
+ # ======================================================================= #
1526
+ @entry_percentage = return_entry_percentage
1527
+ end
1528
+
1529
+ # ========================================================================= #
1530
+ # === return_hbox_containing_three_labels_and_three_entries
1531
+ #
1532
+ # This should only be invoked after the entries were created.
1533
+ # ========================================================================= #
1534
+ def return_hbox_containing_three_labels_and_three_entries
1535
+ _ = gtk_hbox
1536
+
1537
+ # ======================================================================= #
1538
+ # === n questions
1539
+ # ======================================================================= #
1540
+ vbox1 = gtk_vbox
1541
+ label_n_questions = text('n questions').set_font(:hack_15)
1542
+ label_n_questions.center_and_make_bold
1543
+ vbox1.minimal(label_n_questions, 2)
1544
+ vbox1.minimal(@entry_containing_n_questions, 2)
1545
+ _.minimal(vbox1, 2)
1546
+
1547
+ # ======================================================================= #
1548
+ # === n unanswered
1549
+ # ======================================================================= #
1550
+ vbox2 = gtk_vbox
1551
+ label_n_unanswered = text('n unanswered').set_font(:hack_15)
1552
+ label_n_unanswered.make_bold
1553
+ vbox2.minimal(label_n_unanswered, 2)
1554
+ vbox2.minimal(@entry_containing_n_unanswered_questions, 2)
1555
+ _.minimal(vbox2, 2)
1556
+
1557
+ # ======================================================================= #
1558
+ # === n answered
1559
+ # ======================================================================= #
1560
+ vbox3 = gtk_vbox
1561
+ label_n_answered = text('n answered').set_font(:hack_15)
1562
+ label_n_answered.royalblue
1563
+ label_n_answered.center_and_make_bold
1564
+ vbox3.minimal(label_n_answered, 2)
1565
+ vbox3.minimal(@entry_containing_n_answers, 2)
1566
+ _.minimal(vbox3, 2)
1567
+
1568
+ # ======================================================================= #
1569
+ # Last but not least, add the entry showing the percentage values.
1570
+ # ======================================================================= #
1571
+ _.minimal(@entry_percentage, 2)
1572
+ return _
1573
+ end
1574
+
1575
+ # ========================================================================= #
1576
+ # === do_update_the_entry_n_questions
1577
+ # ========================================================================= #
1578
+ def do_update_the_entry_n_questions(
1579
+ current_exam_topic = current_exam_topic?
1580
+ )
1581
+ @entry_containing_n_questions.set_text(
1582
+ return_n_questions_from_the_currently_selected_topic(current_exam_topic).to_s
1583
+ )
1584
+ end; alias update_n_questions do_update_the_entry_n_questions # === update_n_questions
1585
+
1586
+ # ========================================================================= #
1587
+ # === create_the_button_use_random_entry_from_the_ten_aliases
1588
+ # ========================================================================= #
1589
+ def create_the_button_use_random_entry_from_the_ten_aliases
1590
+ # ======================================================================= #
1591
+ # === @button_use_random_entry_from_the_ten_aliases
1592
+ #
1593
+ # This is an eventbox rather than a button, but I think this is still
1594
+ # fine. The unicode character "🕵" (U+1F575) is the spy character.
1595
+ # ======================================================================= #
1596
+ if use_emoji?
1597
+ label = gtk_label('🕵️')
1598
+ else
1599
+ label = image_avatar_default
1600
+ end
1601
+ # ======================================================================= #
1602
+ # === @button_use_random_entry_from_the_ten_aliases
1603
+ # ======================================================================= #
1604
+ @button_use_random_entry_from_the_ten_aliases = gtk_eventbox(label)
1605
+ @button_use_random_entry_from_the_ten_aliases.on_clicked {
1606
+ if @user_configuration[:show_ten_aliases]
1607
+ set_exam_topic(
1608
+ @user_configuration[:show_ten_aliases].return_random_entry
1609
+ )
1610
+ update_n_questions
1611
+ update_n_unanswered
1612
+ do_ask_an_exam_question
1613
+ end
1614
+ }
1615
+ @button_use_random_entry_from_the_ten_aliases.set_size_request(40, 40)
1616
+ @button_use_random_entry_from_the_ten_aliases.lightblue
1617
+ @button_use_random_entry_from_the_ten_aliases.hint =
1618
+ 'Click on this small widget to randomly assign one of '\
1619
+ 'the 10 exam-topics currently being studied as the '\
1620
+ 'new main exam-topic in use.'
1621
+ return @button_use_random_entry_from_the_ten_aliases
1622
+ end
1623
+
1624
+ # ========================================================================= #
1625
+ # === do_update_the_entry_n_unanswered_questions
1626
+ #
1627
+ # This method depends on two entries being set correctly.
1628
+ # ========================================================================= #
1629
+ def do_update_the_entry_n_unanswered_questions
1630
+ _ = @entry_containing_n_questions.text?.to_i -
1631
+ @entry_containing_n_answers.text?.to_i
1632
+ @entry_containing_n_unanswered_questions.set_text(_.to_s)
1633
+ end; alias update_the_entry_n_unanswered_questions do_update_the_entry_n_unanswered_questions # === update_the_entry_n_unanswered_questions
1634
+ alias update_n_unanswered do_update_the_entry_n_unanswered_questions # === update_n_unanswered
1635
+
1636
+ # ========================================================================= #
1637
+ # === do_update_the_entry_n_answered
1638
+ # ========================================================================= #
1639
+ def do_update_the_entry_n_answered(
1640
+ current_exam_topic = @combo_box_available_exam_topics.active_text.to_s.strip.dup,
1641
+ entry = @entry_containing_n_answers # The entry that is to be updated.
1642
+ )
1643
+ current_exam_topic.strip! if current_exam_topic.end_with? '_'
1644
+ entry.set_text(
1645
+ return_n_answers_from_the_currently_selected_topic(current_exam_topic).to_s
1646
+ )
1647
+ end; alias update_n_answered do_update_the_entry_n_answered # === update_n_answered
1648
+
1649
+ # ========================================================================= #
1650
+ # === do_updated_the_entries_n_answered_and_n_unanswered
1651
+ # ========================================================================= #
1652
+ def do_updated_the_entries_n_answered_and_n_unanswered
1653
+ do_update_the_entry_n_unanswered_questions
1654
+ update_n_unanswered
1655
+ end
1656
+
1657
+ # ========================================================================= #
1658
+ # === do_open_the_current_exam_topic_file
1659
+ #
1660
+ # This method can either open the exam-file in the bluefish editor,
1661
+ # or in the integrated ruby-gtk editor. Since as of July 2021 we
1662
+ # will try the integrated variant. Unfortunately ruby-gtk is somehow
1663
+ # buggy - reading a large file leads to a BadAlloc error.
1664
+ # ========================================================================= #
1665
+ def do_open_the_current_exam_topic_file(
1666
+ combo_box_available_exam_topics = @combo_box_available_exam_topics
1667
+ )
1668
+ _ = Studium.find_corresponding_exam_topic(
1669
+ current_exam_topic?
1670
+ )
1671
+ if _.empty? and combo_box_available_exam_topics
1672
+ _ = combo_box_available_exam_topics.active_text.to_s
1673
+ end
1674
+ _ = Studium.path_to_exam_topic?+_
1675
+ if use_the_internal_editor?
1676
+ set_save_into_this_local_file(_)
1677
+ set_editor_buffer(File.read(_))
1678
+ @notebook_tab.focus_on_this_tab(2)
1679
+ else
1680
+ # ===================================================================== #
1681
+ # Or simply use bluefish or whatever else the editor is.
1682
+ # ===================================================================== #
1683
+ esystem "#{@user_configuration[:use_this_editor]} #{_}"
1684
+ end
1685
+ end
1686
+
1687
+ # ========================================================================= #
1688
+ # === answer_is?
1689
+ # ========================================================================= #
1690
+ def answer_is?
1691
+ @answer_is
1692
+ end
1693
+
1694
+ # ========================================================================= #
1695
+ # === array_all_exam_questions?
1696
+ #
1697
+ # Query-method to keep track of all exam-questions that were asked in
1698
+ # the current run.
1699
+ # ========================================================================= #
1700
+ def array_all_exam_questions?
1701
+ @user_configuration[:array_all_exam_questions]
1702
+ end
1703
+
1704
+ # ========================================================================= #
1705
+ # === debug
1706
+ # ========================================================================= #
1707
+ def debug
1708
+ pp array_all_exam_questions?
1709
+ pp array_all_exam_questions?.size
1710
+ end
1711
+
1712
+ # ========================================================================= #
1713
+ # === do_popup_the_array_of_all_exam_questions
1714
+ # ========================================================================= #
1715
+ def do_popup_the_array_of_all_exam_questions
1716
+ content = array_all_exam_questions?.map.with_index {|line, index| index += 1
1717
+ line = line.dup
1718
+ line.prepend(
1719
+ "(#{index}) "
1720
+ )
1721
+ line
1722
+ }.join("\n")
1723
+ text_buffer = gtk_text_buffer(content)
1724
+ text_view = gtk_text_view(text_buffer)
1725
+ scrolled_window = gtk_scrolled_window(text_view)
1726
+ scrolled_window.width_height(1400, 700)
1727
+ scrolled_window.pad8px
1728
+ popup_over_this_widget(
1729
+ entry_exam_topic?,
1730
+ scrolled_window
1731
+ ).popup
1732
+ end
1733
+
1734
+ # ========================================================================= #
1735
+ # === return_event_box_with_face_glasses
1736
+ # ========================================================================= #
1737
+ def return_event_box_with_face_glasses
1738
+ event_box = gtk_event_box
1739
+ image = gtk_icon('face-glasses')
1740
+ event_box.add(image)
1741
+ event_box.on_clicked {
1742
+ do_popup_the_array_of_all_exam_questions
1743
+ }
1744
+ return event_box
1745
+ end
1746
+
1747
+ # ========================================================================= #
1748
+ # === entry_holding_all_exam_topics?
1749
+ # ========================================================================= #
1750
+ def entry_holding_all_exam_topics?
1751
+ @entry_holding_all_exam_topics
1752
+ end; alias entry_ask_questions_from_this_topic? entry_holding_all_exam_topics? # === entry_ask_questions_from_this_topic?
1753
+ alias entry_ask_questions? entry_holding_all_exam_topics? # === entry_ask_questions?
1754
+ alias entry_exam_topic? entry_holding_all_exam_topics? # === exam_topic?
1755
+
1756
+ # ========================================================================= #
1757
+ # === sync_entry_holding_all_exam_topics_onto_the_combo_box
1758
+ #
1759
+ # An alternative to the functionality in this method may be this:
1760
+ #
1761
+ # Studium.find_corresponding_exam_topic "Festkörper Chemie und Geochemie" # => "geochemistry"
1762
+ #
1763
+ # ========================================================================= #
1764
+ def sync_entry_holding_all_exam_topics_onto_the_combo_box(
1765
+ value = @entry_holding_all_exam_topics.text?.
1766
+ downcase.delete(' ').delete('_')
1767
+ )
1768
+ array = available_exam_topics?.map {|entry|
1769
+ entry.delete(' ').downcase
1770
+ }
1771
+ index = array.find_index {|entry| entry.delete('_').include?(value) }
1772
+ if index
1773
+ @combo_box_available_exam_topics.set_active(index)
1774
+ else
1775
+ e 'The index was not found. Input was '+steelblue(value)+'.'
1776
+ end
1777
+ end; alias sync_entry_holding_all_exam_topics_onto_the_main_combo_box sync_entry_holding_all_exam_topics_onto_the_combo_box # === sync_entry_holding_all_exam_topics_onto_the_main_combo_box
1778
+
1779
+ # ========================================================================= #
1780
+ # === return_event_box_for_asking_a_random_exam_topic
1781
+ # ========================================================================= #
1782
+ def return_event_box_for_asking_a_random_exam_topic
1783
+ event_box_for_image_view_refresh_symbolic_symbolic = gtk_event_box(
1784
+ image_view_refresh_symbolic_symbolic
1785
+ )
1786
+ event_box_for_image_view_refresh_symbolic_symbolic.hint =
1787
+ "Click on this icon to <b>set a random exam topic</b>, "\
1788
+ "and then ask an exam question from this topic.\n\n"\
1789
+ "Note that since as of <b>August 2022</b> this will ignore "\
1790
+ "exam topics that were already solved."
1791
+ # ======================================================================= #
1792
+ # Let the event-box respond to an on-click event.
1793
+ # ======================================================================= #
1794
+ event_box_for_image_view_refresh_symbolic_symbolic.on_clicked {
1795
+ do_assign_a_new_exam_topic
1796
+ }
1797
+ return event_box_for_image_view_refresh_symbolic_symbolic
1798
+ end
1799
+
1800
+ # ========================================================================= #
1801
+ # === do_assign_a_new_exam_topic
1802
+ # ========================================================================= #
1803
+ def do_assign_a_new_exam_topic
1804
+ clear_reveal_the_answer
1805
+ this_topic = select_not_yet_completed_exam_topics(
1806
+ available_exam_topics?
1807
+ ).sample # Obtain a random exam topic here.
1808
+ @entry_holding_all_exam_topics.set_text(this_topic.to_s)
1809
+ sync_entry_holding_all_exam_topics_onto_the_combo_box
1810
+ do_ask_an_exam_question
1811
+ update_three_important_widgets
1812
+ end
1813
+
1814
+ # ========================================================================= #
1815
+ # === available_exam_topics?
1816
+ # ========================================================================= #
1817
+ def available_exam_topics?
1818
+ @user_configuration[:available_exam_topics]
1819
+ end
1820
+
1821
+ # ========================================================================= #
1822
+ # === select_not_yet_completed_exam_topics
1823
+ # ========================================================================= #
1824
+ def select_not_yet_completed_exam_topics(i)
1825
+ if i and i.is_a?(Array)
1826
+ return ::Studium.reject_already_completed_exam_topics(i, @hash_dataset_of_all_lectures)
1827
+ end
1828
+ return i # else return the original input unmodified.
1829
+ end
1830
+
1831
+ # ========================================================================= #
1832
+ # === create_the_labels
1833
+ # ========================================================================= #
1834
+ def create_the_labels
1835
+ # ======================================================================= #
1836
+ # === @label_n_questions_were_answered
1837
+ # ======================================================================= #
1838
+ @label_n_questions_were_answered = selectable_label
1839
+ update_the_label_n_questions_were_answered(@label_n_questions_were_answered)
1840
+ end
1841
+
1842
+ # ========================================================================= #
1843
+ # === return_string_how_many_exam_questions_are_already_answered
1844
+ # ========================================================================= #
1845
+ def return_string_how_many_exam_questions_are_already_answered
1846
+ ::Studium.return_string_how_many_exam_questions_are_already_answered
1847
+ end
1848
+
1849
+ # ========================================================================= #
1850
+ # === return_combo_box_available_exam_topics
1851
+ # ========================================================================= #
1852
+ def return_combo_box_available_exam_topics
1853
+ use_this_sorted_array = return_available_exam_topics.uniq.map {|entry|
1854
+ if entry.size > 24 # Truncate it a bit in this case.
1855
+ entry = entry[0 .. 24]
1856
+ end
1857
+ entry
1858
+ }.sort
1859
+
1860
+ _ = combo_box(
1861
+ use_this_sorted_array
1862
+ )
1863
+ _.first_entry_is_active
1864
+ _.bblack1
1865
+ _.set_size_request(100, 28)
1866
+ # ======================================================================= #
1867
+ # Wrap-width determines how many entries per row are shown when the
1868
+ # combo-box is expanded. We stick to the default of 1 here.
1869
+ # ======================================================================= #
1870
+ _.set_wrap_width(1)
1871
+ handle_the_combo_box_available_exam_topics_on_changed_event(_)
1872
+ return _
1873
+ end
1874
+
1875
+ # ========================================================================= #
1876
+ # === run (run tag)
1877
+ # ========================================================================= #
1878
+ def run
1879
+ super()
1880
+ do_style_all_buttons_uniformly
1881
+ deselect_the_entry_containing_the_exam_topic
1882
+ do_handle_the_click_event_for_the_ask_question_button
1883
+ end
1884
+
1885
+ end; end; end; end
1886
+
1887
+ if __FILE__ == $PROGRAM_NAME
1888
+ Studium::GUI::Gtk::ExamQuestionWidget.run
1889
+ end