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,2757 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === Studium::Exams::AskExamQuestion
6
+ #
7
+ # This class, re-written in December 2021 / January 2022 and then again
8
+ # in June 2023, can handle exam questions and study-related questions.
9
+ #
10
+ # The user can pass a given topic to this class, as a String, such as
11
+ # "microbiology", and then this class will randomly select one of the
12
+ # existing entries fitting to that particular topic at hand, and then
13
+ # ask the question, before revealing the answer after a delay. The
14
+ # specified delay is usually fairly small, at about 3 seconds, but
15
+ # this can be set by the user to any different value.
16
+ #
17
+ # The delay, e. g. 3 seconds, is read in from a yaml file (if that
18
+ # file exists, otherwise we will use a default value). Alternatively
19
+ # the delay can be set from the commandline via, for instance:
20
+ #
21
+ # qa 'delay = 5'
22
+ #
23
+ # The topic given thus determines which exam question is to be handled.
24
+ #
25
+ # By default, if no argument is provided to this class, then a random
26
+ # topic (and thus a random question) will be picked, from all the
27
+ # available topics.
28
+ #
29
+ # Every time a question is asked, the "last asked question"
30
+ # information is stored into a file.
31
+ #
32
+ # The "exam pool" constitutes the available, unanswered exams.
33
+ #
34
+ # The method Studium.runmode? will tell us whether we are on
35
+ # the commandline or whether we are used on the www, such as
36
+ # from a .cgi script.
37
+ #
38
+ # The class can operate on one question at a time, or in batch
39
+ # mode, which will call "all questions". (By default, I usually
40
+ # prefer to just have one question asked).
41
+ #
42
+ # Usage examples in ruby code:
43
+ #
44
+ # x = Studium::Exams::ExamQuestion.new('- Wir können Melanome nach der "ABCDE" Regel beurteilen. Wofür stehen diese Abkürzungen? (1) A: Asymmetry (2) B: Border (3) C: Color (4) D: Diameter (5) E: Evolving')
45
+ # x = Studium::Exams::ExamQuestion.new('- Nenne die beiden wichtigsten Mechanismen zur Verhinderung der Selbstbefruchtung. A: (1) physische Trennung von männlichen und weiblichen Gametophyten (2) genetisch, über die Selbst-Inkompatibilität')
46
+ # x = Studium::Exams::ExamQuestion.new('- Nenne die Zucker des Calvin-Zyklus, beginnend von RUBISCO, im "Uhrzeigersinn"! A: (1) 3-Phosphoglycerat (2) 1,3-Bisphosphoglycerat (3) G3P (4) 5-G3P und Ribulose-1-5-Bisphosphat.')
47
+ # x = Studium::Exams::ExamQuestion.new('- abc? def? ya') { :do_not_run_yet }
48
+ #
49
+ # =========================================================================== #
50
+ # require 'studium/exams/ask_exam_question/ask_exam_question.rb'
51
+ # Studium::Exams::AskExamQuestion.new(ARGV)
52
+ # y = Studium.ask_question('amg2') { :do_not_run_yet }
53
+ # =========================================================================== #
54
+ require 'studium/base/base.rb'
55
+
56
+ module Studium
57
+
58
+ module Exams
59
+
60
+ class AskExamQuestion < Studium::Base # === Studium::Exams::AskExamQuestion
61
+
62
+ require 'studium/exams/exam_question/exam_question.rb'
63
+ require 'studium/statistics/report_how_many_exam_questions_were_answered.rb'
64
+
65
+ # ========================================================================= #
66
+ # === DEFAULT_COLOUR_TO_USE
67
+ # ========================================================================= #
68
+ DEFAULT_COLOUR_TO_USE = :olivedrab
69
+
70
+ # ========================================================================= #
71
+ # === USE_THESE_COLOURS
72
+ #
73
+ # This Hash is used to set up colours. It will be passed to methods
74
+ # that belong to the Colours module ("namespace"), which in turn
75
+ # can be found in the gem called "colours".
76
+ #
77
+ # Using a Hash like this allows the user to customize the colours as
78
+ # well.
79
+ #
80
+ # For the question, we prefer to use :olivedrab.
81
+ # ========================================================================= #
82
+ USE_THESE_COLOURS = {
83
+ one: :steelblue,
84
+ two: :mediumseagreen,
85
+ three: :mediumpurple, # ← Used to be 'peru' up until 23.11.2019.
86
+ four: :olivedrab,
87
+ five: :lightgreen,
88
+ default_colour: DEFAULT_COLOUR_TO_USE # Make use of the colour defined above ^^^ here.
89
+ }
90
+
91
+ # ========================================================================= #
92
+ # === DEFAULT_COLOUR_AS_ESCAPE_SEQUENCE
93
+ # ========================================================================= #
94
+ DEFAULT_COLOUR_AS_ESCAPE_SEQUENCE =
95
+ ::Colours.remove_trailing_end_from(
96
+ ::Colours.send(USE_THESE_COLOURS[:default_colour])
97
+ )
98
+
99
+ # ========================================================================= #
100
+ # === EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_QUESTION
101
+ #
102
+ # This constant is like the constant called
103
+ # EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_ANSWER, except that here
104
+ # we work on double-quotes, aka '"' characters, in a question.
105
+ #
106
+ # As of November 2019, this defaults to false, since we already
107
+ # use many other colours at this point.
108
+ # ========================================================================= #
109
+ EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_QUESTION = false
110
+
111
+ # ========================================================================= #
112
+ # === EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_ANSWER
113
+ # ========================================================================= #
114
+ EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_ANSWER = false
115
+
116
+ # ========================================================================= #
117
+ # === MAY_WE_SHOW_THE_TOPIC
118
+ #
119
+ # If MAY_WE_SHOW_THE_TOPIC is true then we show the topic.
120
+ #
121
+ # We will grab the entry from the yaml file, but we have to make sure
122
+ # that the file exists, before loading it..
123
+ # ========================================================================= #
124
+ _ = "#{::Studium.yaml_directory?}show_topic.yml"
125
+ if File.exist? _
126
+ MAY_WE_SHOW_THE_TOPIC = YAML.load_file(_)
127
+ else
128
+ MAY_WE_SHOW_THE_TOPIC = false
129
+ end
130
+
131
+ # ========================================================================= #
132
+ # === SHALL_WE_DEBUG
133
+ #
134
+ # Shall we debug or shall we not debug. This is specific to this
135
+ # class here.
136
+ # ========================================================================= #
137
+ SHALL_WE_DEBUG = false
138
+
139
+ # ========================================================================= #
140
+ # === SHOW_STATISTICS
141
+ #
142
+ # If SHOW_STATISTICS is true then we will show the statistics.
143
+ # ========================================================================= #
144
+ SHOW_STATISTICS = true
145
+
146
+ # ========================================================================= #
147
+ # === STORE_TEXT
148
+ #
149
+ # Next comes the string that we will save if we set a new delay.
150
+ # ========================================================================= #
151
+ STORE_TEXT = '# ====================================================================== #
152
+ # How long to wait before showing the answer in question, in seconds.
153
+ # ====================================================================== #
154
+ delay: '
155
+
156
+
157
+ # ========================================================================= #
158
+ # === @rename_konsole_tab
159
+ # ========================================================================= #
160
+ @rename_konsole_tab = false
161
+
162
+ # ========================================================================= #
163
+ # === Studium::Exams::ExamQuestion.rename_konsole_tab?
164
+ # ========================================================================= #
165
+ def self.rename_konsole_tab?
166
+ @rename_konsole_tab
167
+ end
168
+
169
+ # ========================================================================= #
170
+ # === Studium::Exams::ExamQuestion.set_rename_konsole_tab
171
+ # ========================================================================= #
172
+ def self.set_rename_konsole_tab(i)
173
+ @rename_konsole_tab = i
174
+ end
175
+
176
+ # ========================================================================= #
177
+ # === initialize
178
+ #
179
+ # The very first argument given to this class is usually the topic that
180
+ # is sought - such as "bem1" or "amg1" or "plants", and so forth.
181
+ # ========================================================================= #
182
+ def initialize(
183
+ commandline_arguments = ARGV,
184
+ run_already = true,
185
+ &block
186
+ )
187
+ reset
188
+ set_commandline_arguments(
189
+ commandline_arguments
190
+ )
191
+ # ======================================================================= #
192
+ # === Handle blocks next
193
+ # ======================================================================= #
194
+ if block_given?
195
+ yielded = yield
196
+ case yielded # (case tag)
197
+ # ===================================================================== #
198
+ # === :disable_colours
199
+ # ===================================================================== #
200
+ when :disable_colours,
201
+ :no_colours
202
+ # =================================================================== #
203
+ # The user does not want to use colours in this case, so let's
204
+ # disable colours then.
205
+ # =================================================================== #
206
+ disable_colours
207
+ set_mode :www # ← Experimental as of 13.04.2019.
208
+ # ===================================================================== #
209
+ # === :then_determine_the_split_position_without_using_colours
210
+ # ===================================================================== #
211
+ when :then_determine_the_split_position_without_using_colours
212
+ @internal_hash[:do_determine_the_split_position] = true
213
+ disable_colours
214
+ # ===================================================================== #
215
+ # === :then_determine_the_split_position
216
+ # ===================================================================== #
217
+ when :then_determine_the_split_position
218
+ @internal_hash[:do_determine_the_split_position] = true
219
+ # ===================================================================== #
220
+ # === :then_determine_the_split_position_while_disabling_the_colours
221
+ # ===================================================================== #
222
+ when :then_determine_the_split_position_while_disabling_the_colours
223
+ @internal_hash[:do_determine_the_split_position] = true
224
+ disable_colours
225
+ set_mode :www # ← Experimental as of 13.04.2019.
226
+ # ===================================================================== #
227
+ # === :do_not_run_yet
228
+ # ===================================================================== #
229
+ when :do_not_run_yet
230
+ run_already = false
231
+ end
232
+ end
233
+ case run_already
234
+ # ======================================================================= #
235
+ # === :do_not_run
236
+ #
237
+ # Handle the situation when we do not want to run automatically.
238
+ #
239
+ # This is for arguments such as :dont_run_yet.
240
+ # ======================================================================= #
241
+ when :do_not_run,
242
+ :do_not,
243
+ :dont_run,
244
+ :dont_run_yet,
245
+ :do_not_run_yet
246
+ run_already = false
247
+ # ======================================================================= #
248
+ # === :commandline
249
+ # ======================================================================= #
250
+ when :commandline
251
+ run_already = false
252
+ set_commandline
253
+ end
254
+ run if run_already
255
+ end
256
+
257
+ # ========================================================================= #
258
+ # === reset (reset tag)
259
+ # ========================================================================= #
260
+ def reset
261
+ super()
262
+ infer_the_namespace
263
+ # ======================================================================= #
264
+ # === :dataset_from_the_file
265
+ #
266
+ # The next variable must be initially nil, in order to distinguish it
267
+ # from the the startup-situation, before any exam file has been
268
+ # read in.
269
+ # ======================================================================= #
270
+ @internal_hash[:dataset_from_the_file] = nil
271
+ # ======================================================================= #
272
+ # === :reject_lines_that_end_with_a_done_token
273
+ #
274
+ # If this variable is set to true (which is the default) then all
275
+ # entries that end with [] will be removed.
276
+ # ======================================================================= #
277
+ @internal_hash[:reject_lines_that_end_with_a_done_token] = true
278
+ # ======================================================================= #
279
+ # === :n_exam_questions_in_total
280
+ # ======================================================================= #
281
+ @internal_hash[:n_exam_questions_in_total] = 0
282
+ # ======================================================================= #
283
+ # === :n_exam_questions_answered
284
+ # ======================================================================= #
285
+ @internal_hash[:n_exam_questions_answered] = 0
286
+ # ======================================================================= #
287
+ # === :may_we_show_the_topic
288
+ # ======================================================================= #
289
+ @internal_hash[:may_we_show_the_topic] = MAY_WE_SHOW_THE_TOPIC
290
+ # ======================================================================= #
291
+ # === :delay
292
+ # ======================================================================= #
293
+ @internal_hash[:delay] = 2.8
294
+ # ======================================================================= #
295
+ # === :colour_for_answers
296
+ # ======================================================================= #
297
+ @internal_hash[:colour_for_answers] = nil
298
+ # ======================================================================= #
299
+ # === :colour_for_questions
300
+ # ======================================================================= #
301
+ @internal_hash[:colour_for_questions] = nil
302
+ # ======================================================================= #
303
+ # === :exam_file
304
+ #
305
+ # This instance variable will keep track where the full path to the
306
+ # exam file can be found.
307
+ # ======================================================================= #
308
+ @internal_hash[:exam_file] = nil
309
+ # ======================================================================= #
310
+ # === :debug
311
+ # ======================================================================= #
312
+ @internal_hash[:debug] = SHALL_WE_DEBUG
313
+ # ======================================================================= #
314
+ # === :topic_to_use
315
+ # ======================================================================= #
316
+ @internal_hash[:topic_to_use] = nil
317
+ # ======================================================================= #
318
+ # === :result_for_www
319
+ #
320
+ # This can be a String, which is then used for display on the www.
321
+ #
322
+ # Initially it is set to nil, though, to indicate that we will not
323
+ # need it when in commandline-mode.
324
+ # ======================================================================= #
325
+ @internal_hash[:result_for_www] = nil
326
+ # ======================================================================= #
327
+ # === :use_these_colours
328
+ # ======================================================================= #
329
+ @internal_hash[:use_these_colours] = USE_THESE_COLOURS
330
+ # ======================================================================= #
331
+ # === :numbers_in_parens
332
+ # ======================================================================= #
333
+ @internal_hash[:numbers_in_parens] = false
334
+ # ======================================================================= #
335
+ # === :separator_token_to_use_when_asking_questions_and_revealing_the_answer
336
+ # ======================================================================= #
337
+ if Studium.shall_we_make_use_of_unicode_symbols?
338
+ @internal_hash[:separator_token_to_use_when_asking_questions_and_revealing_the_answer] = Studium.unicode_horizontal_bar
339
+ else
340
+ @internal_hash[:separator_token_to_use_when_asking_questions_and_revealing_the_answer] = '*'
341
+ end
342
+ # ======================================================================= #
343
+ # === @exam_question
344
+ # ======================================================================= #
345
+ @exam_question = Studium::Exams::ExamQuestion.new { :do_not_run_yet }
346
+ set_be_verbose # Be verbose, output lots of stuff to the user.
347
+ try_to_load_custom_colours
348
+ set_delay
349
+ # ======================================================================= #
350
+ # The default colours will not be made available when we run in the www-mode.
351
+ # ======================================================================= #
352
+ if are_we_in_www_mode?
353
+ disable_colours
354
+ end
355
+ end
356
+
357
+ # ========================================================================= #
358
+ # === separator_token_to_use_when_asking_questions_and_revealing_the_answer?
359
+ # ========================================================================= #
360
+ def separator_token_to_use_when_asking_questions_and_revealing_the_answer?
361
+ @internal_hash[:separator_token_to_use_when_asking_questions_and_revealing_the_answer]
362
+ end; alias separator_token_to_be_used? separator_token_to_use_when_asking_questions_and_revealing_the_answer? # === separator_token_to_be_used?
363
+ alias separator_token? separator_token_to_use_when_asking_questions_and_revealing_the_answer? # === separator_token?
364
+
365
+ # ========================================================================= #
366
+ # === result?
367
+ # ========================================================================= #
368
+ def result?
369
+ @internal_hash[:result_for_www]
370
+ end
371
+
372
+ # ========================================================================= #
373
+ # === try_to_load_custom_colours
374
+ #
375
+ # This method can be used to designate specific colours for use by
376
+ # this class.
377
+ # ========================================================================= #
378
+ def try_to_load_custom_colours
379
+ _ = "#{::Studium.project_yaml_directory?}colours/custom_colours.yml"
380
+ if File.exist? _
381
+ dataset = YAML.load_file(_)
382
+
383
+ if dataset.has_key?('colour_for_one')
384
+ @internal_hash[:use_these_colours][:one] = dataset['colour_for_one']
385
+ end
386
+
387
+ if dataset.has_key?('colour_for_two')
388
+ @internal_hash[:use_these_colours][:two] = dataset['colour_for_two']
389
+ end
390
+
391
+ if dataset.has_key?('colour_for_three')
392
+ @internal_hash[:use_these_colours][:three] = dataset['colour_for_three']
393
+ end
394
+
395
+ if dataset.has_key?('colour_for_four')
396
+ @internal_hash[:use_these_colours][:four] = dataset['colour_for_four']
397
+ end
398
+
399
+ if dataset.has_key?('colour_for_five')
400
+ @internal_hash[:use_these_colours][:five] = dataset['colour_for_five']
401
+ end
402
+
403
+ set_colour_for_questions(
404
+ dataset['colour_for_questions']
405
+ )
406
+ set_colour_for_answers(
407
+ dataset['colour_for_answers']
408
+ )
409
+ else
410
+ if is_on_roebe?
411
+ e 'No file could be found at '+sfile(_)+'.'
412
+ end
413
+ end
414
+ end
415
+
416
+ # ========================================================================= #
417
+ # === default_colour?
418
+ # ========================================================================= #
419
+ def default_colour?
420
+ USE_THESE_COLOURS[:default_colour]
421
+ end
422
+
423
+ # ========================================================================= #
424
+ # === set_exam_question_line
425
+ # ========================================================================= #
426
+ def set_exam_question_line(i)
427
+ @exam_question.set_exam_question_line(i)
428
+ end
429
+
430
+ # ========================================================================= #
431
+ # === sleep_default_delay
432
+ #
433
+ # This method can be used to sleep for the specified duration.
434
+ #
435
+ # Since as of April 2012 the method will also handle SIGINT-events
436
+ # gracefully.
437
+ # ========================================================================= #
438
+ def sleep_default_delay(
439
+ i = delay?
440
+ )
441
+ begin
442
+ sleep(i)
443
+ rescue Interrupt # We are silent here.
444
+ exit_program
445
+ end
446
+ end; alias default_sleep sleep_default_delay # === default_sleep
447
+ alias do_sleep sleep_default_delay # === do_sleep
448
+ alias start_default_sleep sleep_default_delay # === start_default_sleep
449
+
450
+ # ========================================================================= #
451
+ # === default_delay?
452
+ # ========================================================================= #
453
+ def default_delay?
454
+ DEFAULT_DELAY
455
+ end
456
+
457
+ # ========================================================================= #
458
+ # === dataset_from_the_file?
459
+ # ========================================================================= #
460
+ def dataset_from_the_file?
461
+ @internal_hash[:dataset_from_the_file]
462
+ end; alias dataset? dataset_from_the_file? # === dataset?
463
+
464
+ # ========================================================================= #
465
+ # === set_dataset_from_the_file
466
+ # ========================================================================= #
467
+ def set_dataset_from_the_file(i)
468
+ @internal_hash[:dataset_from_the_file] = i
469
+ end; alias set_dataset set_dataset_from_the_file # === set_dataset
470
+
471
+ # ========================================================================= #
472
+ # === set_exam_file
473
+ #
474
+ # The file location will be something like:
475
+ #
476
+ # /Programs/Ruby/2.3.1/lib/ruby/site_ruby/2.3.0/studium/exam_topics/physiologie
477
+ #
478
+ # ========================================================================= #
479
+ def set_exam_file(i)
480
+ @internal_hash[:exam_file] = i
481
+ end; alias set_file set_exam_file # === set_file
482
+
483
+ # ========================================================================= #
484
+ # === set_delay
485
+ #
486
+ # Set the default delay value via this method.
487
+ # ========================================================================= #
488
+ def set_delay(
489
+ i = :load_from_file
490
+ )
491
+ case i
492
+ # ======================================================================= #
493
+ # === :default
494
+ # ======================================================================= #
495
+ when :default,
496
+ :load_from_file,
497
+ nil
498
+ # ===================================================================== #
499
+ # === :delay
500
+ # ===================================================================== #
501
+ if File.exist? FILE_DELAY
502
+ i = YAML.load_file(FILE_DELAY)
503
+ i = i['delay'] if i.respond_to?('delay')
504
+ else
505
+ # =================================================================== #
506
+ # This is the default if the file can not be found/read. It
507
+ # can be found in the file studium/constants/delay.rb.
508
+ # =================================================================== #
509
+ i = DEFAULT_DELAY
510
+ end
511
+ end
512
+ if i.is_a? Hash
513
+ i = i['delay']
514
+ end
515
+ @internal_hash[:delay] = i.to_f
516
+ end; alias determine_the_default_delay set_delay # === determine_the_default_delay
517
+ alias delay= set_delay # === delay=
518
+
519
+ # ========================================================================= #
520
+ # === show_the_header
521
+ # ========================================================================= #
522
+ def show_the_header(
523
+ topic_to_use = topic_to_use?
524
+ )
525
+ e steelblue(topic_to_use)
526
+ end
527
+
528
+ # ========================================================================= #
529
+ # === show_available_topics (topics tag)
530
+ #
531
+ # This method will show which topics are all available.
532
+ #
533
+ # By default, it will also exit after having done so.
534
+ #
535
+ # To invoke this method, try:
536
+ #
537
+ # qa topics?
538
+ # qa --show-available-topics
539
+ #
540
+ # ========================================================================= #
541
+ def show_available_topics(
542
+ shall_we_exit = true
543
+ )
544
+ e
545
+ use_these_topics = Studium.available_topics.sort # And sort it.
546
+ use_these_topics.each_with_index {|category, index|
547
+ # ===================================================================== #
548
+ # Number the results via the index.
549
+ # ===================================================================== #
550
+ index = '%4s' % ('('+(index+1).to_s)
551
+ result = ' '.dup
552
+ if use_colours?
553
+ result << ::Colours::CYAN if commandline?
554
+ end
555
+ result << "#{index}) - " # Add the index here.
556
+ if use_colours? # And "close" the escape-sequences next.
557
+ result << rev if commandline?
558
+ end
559
+ category = category.to_s.delete('_')
560
+ category = steelblue(category) if use_colours?
561
+ result << category
562
+ e result
563
+ }
564
+ e
565
+ exit if shall_we_exit
566
+ end
567
+
568
+ # ========================================================================= #
569
+ # === numbers_in_parens?
570
+ # ========================================================================= #
571
+ def numbers_in_parens?
572
+ @internal_hash[:numbers_in_parens]
573
+ end
574
+
575
+ # ========================================================================= #
576
+ # === do_reveal_the_answer (answer tag, answers tag, reveal tag, show tag)
577
+ #
578
+ # This method will show the proper answer to the given exam question as
579
+ # hand.
580
+ #
581
+ # The second argument to this method, called `include_numbers_in_parens`,
582
+ # can be used to keep track as to whether we have numbers such as (2).
583
+ # ========================================================================= #
584
+ def do_reveal_the_answer(
585
+ use_this_answer = @exam_question.answer?,
586
+ include_numbers_in_parens = numbers_in_parens?,
587
+ padding_to_use = ' ',
588
+ use_colours = use_colours?
589
+ )
590
+ # ======================================================================= #
591
+ # The variable result will eventually contain what we will display to
592
+ # the user.
593
+ # ======================================================================= #
594
+ result = padding_to_use.dup # Use four spaces as indent, since as of March 2023.
595
+ # ======================================================================= #
596
+ # Try to cut down at about 76 characters per line, or whatever the
597
+ # limit-per-line is. We have to ignore special tags, though, such
598
+ # as <u> or <orange>. We also have to call this BEFORE replacing
599
+ # these tags with the corresponding escape values.
600
+ # ======================================================================= #
601
+ unless include_numbers_in_parens
602
+ string_without_tags = remove_tags_from_this_input(use_this_answer.dup)
603
+ n_characters_to_consider_in_the_line = string_without_tags.size
604
+ if n_characters_to_consider_in_the_line > word_wrap_at?
605
+ use_this_answer = word_wrap(use_this_answer, word_wrap_at?) # word-wrap is a value such as 85.
606
+ use_this_answer.gsub!(/\n/, N+LEFT_PADDING) if use_this_answer.include? N # Also pad these newlines.
607
+ end
608
+ end
609
+ #use_this_colour = ::Colours.send(colour_for_answers?) { :omit_end } if use_colours?
610
+ # ======================================================================= #
611
+ # Next we must replace the number-words with the corresponding HTML
612
+ # colour. So, for instance, <one> will eventually become
613
+ # <steelblue>.
614
+ # ======================================================================= #
615
+ _ = ::Colours.replace_number_words_with_the_corresponding_html_colour(
616
+ use_this_answer,
617
+ USE_THESE_COLOURS.merge(default_colour: colour_for_answers?)
618
+ )
619
+ result << ::Colours.fancy_parse(_, colour_for_answers?)
620
+ # if exam_answer.include? 'IMAGE: '
621
+ # image_path = exam_answer.scan(/IMAGE: (.+)$/).flatten
622
+ # image_path = image_path.first if image_path.is_a? Array
623
+ # system("tiv #{image_path}")
624
+ # exam_answer.sub!(/IMAGE: (.+)$/, '')
625
+ # end
626
+ # ======================================================================= #
627
+ # === Handle URLs next
628
+ # ======================================================================= #
629
+ if use_this_answer.include? ' URL:' # This is the valid form; the check is necessary.
630
+ # ===================================================================== #
631
+ # Since as of May 2022, if we are on a roebe-system, we will also
632
+ # assign to the xorg-buffer next. We have to supply a regex to do
633
+ # this for us.
634
+ # ===================================================================== #
635
+ use_this_regex = /URL: (https?.*)/ # See: https://rubular.com/r/xJfOSCoi0Q7TWS
636
+ use_this_answer =~ use_this_regex
637
+ set_xorg_buffer($1.to_s.dup)
638
+ use_this_answer = assign_url(use_this_answer)
639
+ # ======================================================================= #
640
+ # === Handle entries that include the substring ' https://'
641
+ # ======================================================================= #
642
+ elsif use_this_answer.include? ' https://'
643
+ use_this_answer = colourize_https_substring(use_this_answer) if use_colours?
644
+ end
645
+ if use_this_answer.include?(' URL:') or use_this_answer.include?(' https://')
646
+ assign_url_or_colourize_https_substring(use_this_answer) if use_colours?
647
+ end
648
+ # ======================================================================= #
649
+ # === Get rid of (2) and similar numbers
650
+ #
651
+ # We assume this to also include (1) and (3) and so forth here.
652
+ # ======================================================================= #
653
+ if use_this_answer.include? '(2)'
654
+ # ===================================================================== #
655
+ # Do a word wrap if the size range from the part up to the first
656
+ # '(' is larger than the allowed characters per line.
657
+ #
658
+ # Since as of August 2019 we will honour HTML colour-tags though
659
+ # and add that to the subrange size.
660
+ # ===================================================================== #
661
+ subrange = use_this_answer[0 .. (use_this_answer.index('(') - 1)].dup
662
+ subrange_size = subrange.size
663
+ if does_this_line_include_a_html_colour?(subrange)
664
+ subrange_size += return_this_line_has_n_characters_as_html_colour_tags(subrange)
665
+ end
666
+ if subrange_size > word_wrap_at?
667
+ use_this_answer[0 .. (use_this_answer.index('(') - 1)] = ''.dup
668
+ subrange = word_wrap(subrange, word_wrap_at?).dup+N
669
+ use_this_answer[0,0] = subrange
670
+ end
671
+ 12.times { |iteration_number_n|
672
+ if use_colours
673
+ # ================================================================= #
674
+ # Colourize the parens - and also add a leading newline.
675
+ # ================================================================= #
676
+ replace_with_this = N+
677
+ ' '+
678
+ rev+
679
+ slategray('(')+
680
+ skyblue(iteration_number_n.to_s.chomp)+
681
+ slategray(')')
682
+ use_this_colour = ::Colours.send(colour_for_answers?) { :omit_end }
683
+ replace_with_this << use_this_colour
684
+ # ================================================================= #
685
+ # Then perform a .gsub next:
686
+ # ================================================================= #
687
+ result.gsub!(/\(#{iteration_number_n}\)/, replace_with_this)
688
+ else
689
+ result.gsub!(/\(#{iteration_number_n}\)/,
690
+ N+'('+iteration_number_n.to_s+')') # Will add a leading newline.
691
+ end
692
+ } # The above is equivalent to the below, by the way:
693
+ # exam_answer.gsub!(/\(6\)/, N+'(6)')
694
+ end
695
+ # ======================================================================= #
696
+ # Next, consider colourizing all questions that have at the least 2
697
+ # '"' characters. These will be colourized if a certain constant is
698
+ # set to true.
699
+ # ======================================================================= #
700
+ if EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_QUESTION and !include_numbers_in_parens
701
+ if use_colours and commandline? and (use_this_answer.count('"') > 1)
702
+ use_this_answer = use_this_answer.dup
703
+ use_this_regex = /"(.+?\s*.*?)"/ # See: https://rubular.com/r/6WK5NjMJld
704
+ # =================================================================== #
705
+ # Next make use of the default colour to use.
706
+ # =================================================================== #
707
+ use_this_colour = ::Colours.send(colour_for_questions?) { :omit_end }
708
+ use_this_answer.gsub!(
709
+ use_this_regex,
710
+ '"'+forestgreen('\1'.delete(N))+ # forestgreen is the hardcoded colour to be used for now.
711
+ use_this_colour+'"'
712
+ )
713
+ end
714
+ end
715
+ # ======================================================================= #
716
+ # === Handle entries that are between <ud>foo</ud> tags
717
+ # ======================================================================= #
718
+ if line_contains_underline_token?(result) and use_colours?
719
+ # ===================================================================== #
720
+ # Colourize <ud> for underline next:
721
+ # ===================================================================== #
722
+ result = replace_underline_token_with_default_colour(result).to_s+
723
+ colour_for_answers?.to_s
724
+ end
725
+ # ======================================================================= #
726
+ # === Handle italic text next
727
+ # ======================================================================= #
728
+ if line_contains_italic_token?(result) and use_colours?
729
+ # ===================================================================== #
730
+ # Colourize <i> for italic next:
731
+ # ===================================================================== #
732
+ append_this = ''.dup
733
+ if ::Colours.respond_to? use_this_colour.to_sym
734
+ append_this << ::Colours.send(use_this_colour,'')
735
+ else
736
+ append_this << use_this_colour
737
+ end
738
+ result = replace_italic_token_with_default_colour(result)+
739
+ append_this
740
+ end
741
+ # ======================================================================= #
742
+ # === Handle entries that are between <b>foo</b> tags
743
+ # ======================================================================= #
744
+ if line_contains_bold_token?(result) and use_colours?
745
+ # ===================================================================== #
746
+ # Colourize <b> for bold font-style next:
747
+ # ===================================================================== #
748
+ result = replace_bold_token_with_default_colour(result)+
749
+ use_this_colour
750
+ end
751
+ # ======================================================================= #
752
+ # === Colourize https-links, if we use colours.
753
+ # This will also include links to wikipedia.
754
+ # ======================================================================= #
755
+ if use_colours? and result.include?('https://')
756
+ use_this_regex =
757
+ /(https:\/\/.+)$/ # See: https://rubular.com/r/drYvZc4a91
758
+ result.sub!(use_this_regex, mediumaquamarine('\\1'))
759
+ end
760
+ if result.include?(' URL:')
761
+ result.gsub!(/ URL:/, royalblue(' →'))
762
+ end
763
+ if result.include? "\n"
764
+ result = result.split("\n").map {|entry|
765
+ entry = entry.dup if entry.frozen?
766
+ entry.lstrip!
767
+ entry.prepend(padding_to_use) unless entry.start_with?(padding_to_use)
768
+ entry
769
+ }.join("\n")
770
+ end
771
+ result << "\n\n"
772
+ # ======================================================================= #
773
+ # Add a <div> element if we run in www-mode.
774
+ # ======================================================================= #
775
+ if www_mode?
776
+ e '<div id="answer_div">'+N
777
+ e use_this_answer
778
+ e "</div>\n"
779
+ else
780
+ e "#{result.rstrip}\n\n"
781
+ end
782
+ end; alias reveal_the_exam_answer do_reveal_the_answer # === reveal_the_exam_answer
783
+ alias reveal_the_answer do_reveal_the_answer # === reveal_the_answer
784
+ alias show_this_answer do_reveal_the_answer # === show_this_answer
785
+ alias show_the_answer do_reveal_the_answer # === show_the_answer
786
+ alias show_answer do_reveal_the_answer # === show_answer
787
+
788
+ # ========================================================================= #
789
+ # === topic_to_use?
790
+ # ========================================================================= #
791
+ def topic_to_use?
792
+ @internal_hash[:topic_to_use]
793
+ end; alias last_topic? topic_to_use? # === last_topic?
794
+ alias topic? topic_to_use? # === topic?
795
+ alias topic topic_to_use? # === topic
796
+ alias exam_topic? topic_to_use? # === exam_topic?
797
+ alias exam_title? topic_to_use? # === exam_title?
798
+ alias which_topic? topic_to_use? # === which_topic?
799
+ alias title topic_to_use? # === title
800
+ alias title? topic_to_use? # === title?
801
+ alias category? topic_to_use? # === category?
802
+
803
+ # ========================================================================= #
804
+ # === word_wrap_at?
805
+ # ========================================================================= #
806
+ def word_wrap_at?
807
+ @exam_question.word_wrap_at?
808
+ end
809
+
810
+ # ========================================================================= #
811
+ # === exam_answer?
812
+ # ========================================================================= #
813
+ def exam_answer?
814
+ @exam_question.answer?
815
+ end; alias answer? exam_answer? # === answer
816
+
817
+ # ========================================================================= #
818
+ # === colour_for_answers?
819
+ # ========================================================================= #
820
+ def colour_for_answers?
821
+ @internal_hash[:colour_for_answers]
822
+ end
823
+
824
+ # ========================================================================= #
825
+ # === colour_for_questions?
826
+ # ========================================================================= #
827
+ def colour_for_questions?
828
+ @internal_hash[:colour_for_questions]
829
+ end
830
+
831
+ # ========================================================================= #
832
+ # === line_contains_underline_token?
833
+ # ========================================================================= #
834
+ def line_contains_underline_token?(i)
835
+ @exam_question.line_contains_underline_token?(i)
836
+ end
837
+
838
+ # ========================================================================= #
839
+ # === line_contains_italic_token?
840
+ # ========================================================================= #
841
+ def line_contains_italic_token?(i)
842
+ @exam_question.line_contains_italic_token?(i)
843
+ end
844
+
845
+ # ========================================================================= #
846
+ # === line_contains_bold_token?
847
+ # ========================================================================= #
848
+ def line_contains_bold_token?(i)
849
+ @exam_question.line_contains_bold_token?(i)
850
+ end
851
+
852
+ # ========================================================================= #
853
+ # === show_line
854
+ # ========================================================================= #
855
+ def show_line
856
+ e exam_question_line?
857
+ end
858
+
859
+ # ========================================================================= #
860
+ # === append_into_onto_daily_exam_questions_file
861
+ # ========================================================================= #
862
+ def append_into_onto_daily_exam_questions_file
863
+ log_dir = "#{log_dir?}daily_exam_questions/"
864
+ mkdir(log_dir) unless File.directory?(log_dir)
865
+ target_file = "#{log_dir}#{dd_mm_yyyy}_daily_exam_questions.md"
866
+ unless File.exist? target_file
867
+ append_what_into(
868
+ '# === Created on '+dd_mm_yyyy+' at '+hh_mm_ss+"\n",
869
+ target_file
870
+ )
871
+ end
872
+ append_what_into("#{line?}\n", target_file)
873
+ end
874
+
875
+ # ========================================================================= #
876
+ # === return_the_full_expanded_exam_title
877
+ # ========================================================================= #
878
+ def return_the_full_expanded_exam_title(exam_title = exam_title?)
879
+ return Studium.find_corresponding_exam_title(exam_title)
880
+ end
881
+
882
+ # ========================================================================= #
883
+ # === n_questions_already_answered?
884
+ # ========================================================================= #
885
+ def n_questions_already_answered?
886
+ @internal_hash[:n_exam_questions_answered]
887
+ end
888
+
889
+ # ========================================================================= #
890
+ # === set_exam_pool
891
+ #
892
+ # The "exam pool" constitutes the available, unanswered exams.
893
+ #
894
+ # What this means, essentially, is that every line ending with a '[]'
895
+ # will be disregarded.
896
+ # ========================================================================= #
897
+ def set_exam_pool(i = nil)
898
+ @internal_hash[:exam_pool] = i
899
+ end
900
+
901
+ # ========================================================================= #
902
+ # === show_how_many_exam_questions_were_already_solved_in_german
903
+ #
904
+ # Similar to the above, except that we will report in german.
905
+ #
906
+ # Invocation example:
907
+ #
908
+ # qa --solved-in-german
909
+ #
910
+ # ========================================================================= #
911
+ def show_how_many_exam_questions_were_already_solved_in_german
912
+ Studium::Exams.report_how_many_exam_questions_were_already_solved(:german)
913
+ end
914
+
915
+ # ========================================================================= #
916
+ # === generate_statistical_webpage
917
+ #
918
+ # Invoke like so:
919
+ #
920
+ # qa --www
921
+ #
922
+ # ========================================================================= #
923
+ def generate_statistical_webpage
924
+ require 'studium/statistics/report_how_many_exam_questions_were_answered.rb'
925
+ Studium::Statistics::ReportHowManyExamQuestionsWereAnswered.generate_webpage
926
+ target = return_pwd+'/Studium/html/statistics.html'
927
+ open_in_browser(target)
928
+ end
929
+
930
+ # ========================================================================= #
931
+ # === main_file_exists?
932
+ # ========================================================================= #
933
+ def main_file_exists?(
934
+ i = exam_file?
935
+ )
936
+ i and File.exist?(i)
937
+ end
938
+
939
+ # ========================================================================= #
940
+ # === edit_sanitize_topics_in_vim
941
+ #
942
+ # To trigger this, do:
943
+ #
944
+ # qa --vim
945
+ #
946
+ # ========================================================================= #
947
+ def edit_sanitize_topics_in_vim
948
+ position_in_the_file = 445
949
+ file =
950
+ RUBY_STUDIUM_HOME_DIR+'toplevel_methods/find_exam_topic_and_exam_title.rb'
951
+ _ = 'vim '+file+' +'+position_in_the_file.to_s
952
+ esystem _
953
+ end
954
+
955
+ # ========================================================================= #
956
+ # === show_content_of_this_topic
957
+ #
958
+ # Invocation example:
959
+ #
960
+ # qa ethik --show-everything
961
+ #
962
+ # ========================================================================= #
963
+ def show_content_of_this_topic(
964
+ i = topic?
965
+ )
966
+ dataset = filter_away_invalid_questions(
967
+ File.readlines(directory_to_the_exam_topics?+i)
968
+ )
969
+ dataset.each {|line|
970
+ e " #{simp(line.chomp)}"
971
+ }
972
+ end
973
+
974
+ # ========================================================================= #
975
+ # === try_to_save_the_line (save tag)
976
+ #
977
+ # This is called whenever the main line is obtained. The original line
978
+ # is copied, not any modified variant.
979
+ #
980
+ # We will store into a file, which is kept at @store_where.
981
+ #
982
+ # It usually defaults to the file /Depot/Studium/last_question_asked.md
983
+ # or wherever else the base-directory has been defined.
984
+ # ========================================================================= #
985
+ def try_to_save_the_line(
986
+ i = line?
987
+ )
988
+ _ = store_where? # Where to store.
989
+ if File.exist?(File.dirname(_))
990
+ if debug?
991
+ opne "Now saving: #{bold_blue(i)} into the file #{sfile(_)}"
992
+ end if commandline?
993
+ if File.writable?(File.dirname(_)) # Make sure the base-directory is writeable here.
994
+ write_what_into(i, _) # Save it.
995
+ end
996
+ end
997
+ end
998
+
999
+ # ========================================================================= #
1000
+ # === set_default_topic_for_the_gui
1001
+ # ========================================================================= #
1002
+ def set_default_topic_for_the_gui(
1003
+ what,
1004
+ into = "#{log_dir?}use_this_exam_topic.yml"
1005
+ )
1006
+ opne "Now setting the default topic to `#{simp(what)}`."
1007
+ write_what_into(what, into)
1008
+ end
1009
+
1010
+ # ========================================================================= #
1011
+ # === tell_whether_we_will_rename_the_kde_konsole_tab
1012
+ # ========================================================================= #
1013
+ def tell_whether_we_will_rename_the_kde_konsole_tab
1014
+ e 'Will we rename the KDE konsole tab? '+
1015
+ simp(
1016
+ VerboseTruth[load_file_rename_konsole_tab.to_s]
1017
+ )
1018
+ end
1019
+
1020
+ # ========================================================================= #
1021
+ # === store_where?
1022
+ # ========================================================================= #
1023
+ def store_where?
1024
+ Studium.file_last_question_asked?
1025
+ end
1026
+
1027
+ # ========================================================================= #
1028
+ # === report_file_does_not_exist
1029
+ # ========================================================================= #
1030
+ def report_file_does_not_exist(
1031
+ this_file = exam_file?
1032
+ )
1033
+ opne "#{rev}No file at `#{sfile(this_file)}` exists."
1034
+ end
1035
+
1036
+ require 'studium/toplevel_methods/set_last_file_for_exam_questions.rb'
1037
+ # ========================================================================= #
1038
+ # === register_last_modified_file
1039
+ # ========================================================================= #
1040
+ def register_last_modified_file(
1041
+ i = exam_file?
1042
+ )
1043
+ Studium.set_last_file_for_exam_questions(i) # , :be_verbose
1044
+ end
1045
+
1046
+ require 'studium/toplevel_methods/n_questions_available.rb'
1047
+ # ========================================================================= #
1048
+ # === show_how_many_exam_questions_are_available
1049
+ #
1050
+ # This method can be called by passing in 'TOTAL' as argument.
1051
+ #
1052
+ # Example:
1053
+ #
1054
+ # qa TOTAL?
1055
+ #
1056
+ # ========================================================================= #
1057
+ def show_how_many_exam_questions_are_available
1058
+ n_questions = ::Studium.n_questions_available?.to_s
1059
+ result = 'Total amount of registered questions: '.dup
1060
+ if commandline? and use_colours?
1061
+ result << simp(n_questions.to_s)
1062
+ else
1063
+ result << n_questions.to_s
1064
+ end
1065
+ e result
1066
+ end; alias total show_how_many_exam_questions_are_available # === total (total tag)
1067
+ alias n_total_questions_available? show_how_many_exam_questions_are_available # === n_total_questions_available?
1068
+
1069
+ # ========================================================================= #
1070
+ # === opnn
1071
+ # ========================================================================= #
1072
+ def opnn
1073
+ super(
1074
+ namespace: namespace?,
1075
+ use_colours: use_colours?
1076
+ )
1077
+ end
1078
+
1079
+ # ========================================================================= #
1080
+ # === determine_whether_we_will_rename_the_konsole_tab
1081
+ #
1082
+ # This method should be called from within the method called reset().
1083
+ # ========================================================================= #
1084
+ def determine_whether_we_will_rename_the_konsole_tab
1085
+ if is_on_roebe?
1086
+ if File.exist? FILE_RENAME_KONSOLE_TAB
1087
+ _ = load_file_rename_konsole_tab
1088
+ if _ == true
1089
+ do_rename_konsole_tab
1090
+ else
1091
+ do_not_rename_konsole_tab
1092
+ end
1093
+ else
1094
+ do_not_rename_konsole_tab
1095
+ end
1096
+ else
1097
+ do_not_rename_konsole_tab
1098
+ end
1099
+ end
1100
+
1101
+ # ========================================================================= #
1102
+ # === show_last_question_asked
1103
+ #
1104
+ # This will show the last question asked.
1105
+ # ========================================================================= #
1106
+ def show_last_question_asked(
1107
+ i = store_where?
1108
+ )
1109
+ if File.exist? i
1110
+ e File.read(i)
1111
+ end
1112
+ end
1113
+
1114
+ # ========================================================================= #
1115
+ # === consider_renaming_konsole_tab
1116
+ #
1117
+ # We will delegate to class SetTerminalTitle in order to rename the KDE
1118
+ # konsole title.
1119
+ # ========================================================================= #
1120
+ def consider_renaming_konsole_tab
1121
+ if Studium::Exams::AskExamQuestion.rename_konsole_tab?
1122
+ rename_kde_konsole_tab(topic?)
1123
+ end
1124
+ end
1125
+
1126
+ # ========================================================================= #
1127
+ # === do_rename_konsole_tab
1128
+ # ========================================================================= #
1129
+ def do_rename_konsole_tab
1130
+ Studium::Exams::AskExamQuestion.set_rename_konsole_tab(true)
1131
+ end
1132
+
1133
+ # ========================================================================= #
1134
+ # === do_not_rename_konsole_tab
1135
+ # ========================================================================= #
1136
+ def do_not_rename_konsole_tab
1137
+ Studium::Exams::AskExamQuestion.set_rename_konsole_tab(false)
1138
+ end
1139
+
1140
+ require 'studium/toplevel_methods/download.rb'
1141
+ # ========================================================================= #
1142
+ # === download_exam_topics
1143
+ #
1144
+ # You can use this method to download all exam topics.
1145
+ #
1146
+ # To call this, do:
1147
+ #
1148
+ # qa --dexamtopics
1149
+ #
1150
+ # ========================================================================= #
1151
+ def download_exam_topics
1152
+ Studium.download_exam_topics
1153
+ end
1154
+
1155
+ # ========================================================================= #
1156
+ # === exam_pool?
1157
+ # ========================================================================= #
1158
+ def exam_pool?
1159
+ @internal_hash[:exam_pool]
1160
+ end
1161
+
1162
+ # ========================================================================= #
1163
+ # === assign_url
1164
+ #
1165
+ # Only call this method after making a line.include? 'URL:' check.
1166
+ # The reason for this is that we will only apply this method on
1167
+ # a line that has this substring representing a remote URL.
1168
+ # ========================================================================= #
1169
+ def assign_url(i)
1170
+ if use_unicode_symbols?
1171
+ nice_token = '➡' # We will use a slightly prettier symbol for Unicode in this case.
1172
+ else
1173
+ nice_token = '=>'
1174
+ end
1175
+ i =~ /URL:\s*(.*)( |)/
1176
+ url = sanitize_url($1.to_s.dup) # URL is something like: "http://de.wikipedia.org/wiki/Ester"
1177
+ url = url.first if url.is_a? Array
1178
+ i = i.dup if i.frozen?
1179
+ begin
1180
+ # ===================================================================== #
1181
+ # The next regex shall also check for input such as:
1182
+ #
1183
+ # URL: https://en.wikipedia.org/wiki/2,4-Dinitrophenol
1184
+ # URL: https://en.wikipedia.org/wiki/File:Histidin_-_Histidine.svg
1185
+ #
1186
+ # Since as of 11.11.2018, we also include any other entry that
1187
+ # starts with 'https:'.
1188
+ # ===================================================================== #
1189
+ if $1 # See: https://rubular.com/r/rNeLS2MH6f
1190
+ remote_URL = $1.to_s.dup
1191
+ i.gsub!(/URL:\s*(.*)( |)/, nice_token+' \1') # ← Also add a '=>' token.
1192
+ if is_on_roebe?
1193
+ # ================================================================= #
1194
+ # Store this on my home system in a file, in this case.
1195
+ # ================================================================= #
1196
+ what = "#{remote_URL}\n"
1197
+ into = log_dir?+'last_exam_questions_URL.md'
1198
+ append_what_into(what, into)
1199
+ end
1200
+ end
1201
+ i = i.to_s.dup
1202
+ return i
1203
+ rescue Exception => error
1204
+ e "Debugging for `#{sfancy(i.to_s)}`:"
1205
+ pp error
1206
+ p url.class
1207
+ e sfancy(url)
1208
+ end
1209
+ end
1210
+
1211
+ # ========================================================================= #
1212
+ # === open_the_last_file_via_your_editor
1213
+ # ========================================================================= #
1214
+ def open_the_last_file_via_your_editor(
1215
+ this_file = last_file?
1216
+ )
1217
+ open_this_file_in_editor(this_file)
1218
+ end
1219
+
1220
+ # ========================================================================= #
1221
+ # === open_this_file_in_editor
1222
+ #
1223
+ # Open this file in the editor.
1224
+ # ========================================================================= #
1225
+ def open_this_file_in_editor(
1226
+ this_file = __FILE__
1227
+ )
1228
+ use_this_editor = editor?
1229
+ # ======================================================================= #
1230
+ # Since as of December 2017, on my home system, I will use nano instead.
1231
+ # ======================================================================= #
1232
+ use_this_editor = 'nano -w' if is_on_roebe?
1233
+ _ = "#{use_this_editor} #{this_file}" #&
1234
+ esystem _
1235
+ end
1236
+
1237
+ # ========================================================================= #
1238
+ # === notify_the_user_that_all_questions_have_been_answered_already
1239
+ # ========================================================================= #
1240
+ def notify_the_user_that_all_questions_have_been_answered_already(
1241
+ which_topic = which_topic?
1242
+ )
1243
+ opne 'All questions have already been answered '
1244
+ opne "for the topic `#{orange(which_topic)}`. "\
1245
+ "#{slateblue(cheering_person?)}"
1246
+ end
1247
+
1248
+ # ========================================================================= #
1249
+ # === custom_colours?
1250
+ # ========================================================================= #
1251
+ def custom_colours?
1252
+ [
1253
+ @internal_hash[:colour_for_questions],
1254
+ @internal_hash[:colour_for_answers]
1255
+ ]
1256
+ end
1257
+
1258
+ # ========================================================================= #
1259
+ # === show_filesize_of_all_exams
1260
+ #
1261
+ # To call this method, do:
1262
+ #
1263
+ # qa --filesize?
1264
+ #
1265
+ # ========================================================================= #
1266
+ def show_filesize_of_all_exams
1267
+ this_exam_topic = directory_of_the_exam_topics?
1268
+ all_filesizes = Dir["#{this_exam_topic}*"].map {|entry|
1269
+ File.size?(entry)
1270
+ }
1271
+ sum = all_filesizes.sum
1272
+ sum_in_kb = sum / 1000.0
1273
+ sum_in_mb = sum_in_kb / 1000.0
1274
+ e "#{rev}The total file size of all exams in "\
1275
+ "#{sdir(this_exam_topic)} is:"
1276
+ e
1277
+ e ' '+simp(sum.to_s)+
1278
+ ' Bytes ('+
1279
+ sfancy(sum_in_mb.round(2).to_s)+' MB)'
1280
+ e
1281
+ end
1282
+
1283
+ # ========================================================================= #
1284
+ # === colourize_https_substring
1285
+ #
1286
+ # Input that passes into the following method, can look like this:
1287
+ #
1288
+ # 'Das "CDT-Toxin". => https://www.ncbi.nlm.nih.gov/pubmed/24253566'
1289
+ #
1290
+ # ========================================================================= #
1291
+ def colourize_https_substring(i)
1292
+ if i.include? 'https://'
1293
+ use_this_regex = /(https:\/\/.+)/ # See: https://rubular.com/r/4quDI8hKxS
1294
+ i =~ use_this_regex
1295
+ i.gsub!(use_this_regex, slateblue('\1')) if $1
1296
+ end
1297
+ return i
1298
+ end
1299
+
1300
+ # ========================================================================= #
1301
+ # === assign_url_or_colourize_https_substring
1302
+ # ========================================================================= #
1303
+ def assign_url_or_colourize_https_substring(i)
1304
+ if i.include?(' URL:')
1305
+ assign_url(i)
1306
+ elsif i.include?(' https://')
1307
+ colourize_https_substring(i)
1308
+ end
1309
+ end
1310
+
1311
+ # ========================================================================= #
1312
+ # === menu_on_the_commandline_as_a_string
1313
+ # ========================================================================= #
1314
+ def menu_on_the_commandline_as_a_string(
1315
+ i = commandline_as_string
1316
+ )
1317
+ case i
1318
+ # ======================================================================= #
1319
+ # === qa --open
1320
+ #
1321
+ # This entry point can be used to open an exam topic file via the
1322
+ # editor.
1323
+ #
1324
+ # A commandline example follows:
1325
+ #
1326
+ # qa ab2 open
1327
+ #
1328
+ # ======================================================================= #
1329
+ when /open (.+)/,
1330
+ /(.+) open/
1331
+ topic = $1.to_s.dup # Example: qa --open amg
1332
+ topic = find_corresponding_exam_topic(topic)
1333
+ topic = ::Studium.directory_to_my_exam_topics+File.basename(topic)
1334
+ open_this_file_in_editor(topic)
1335
+ exit
1336
+ # ======================================================================= #
1337
+ # === qa "delay = 3.0"
1338
+ #
1339
+ # Invoke this like so:
1340
+ #
1341
+ # qa delay = 3.0
1342
+ #
1343
+ # ======================================================================= #
1344
+ when /^DELAY =? ?(\d{0,1}.\d{1})/i,
1345
+ /^DEL =? ?(\d{0,1}.\d{1})/i,
1346
+ /^set_delay =? ?(\d{0,1}.\d{1})/i,
1347
+ /^set_delay :? ?(\d{0,1}.\d{1})/i,
1348
+ /^set_delay ?(\d{0,1}.\d{1})/i # === qa set_delay 3.1
1349
+ _ = $1.to_s.dup
1350
+ set_and_store_delay(_)
1351
+ end
1352
+ end
1353
+
1354
+ # ========================================================================= #
1355
+ # === exam_file?
1356
+ #
1357
+ # This query-method shows as to where the specific file at hand is.
1358
+ # ========================================================================= #
1359
+ def exam_file?
1360
+ @internal_hash[:exam_file]
1361
+ end; alias file? exam_file? # === file?
1362
+ alias which_file? exam_file? # === which_file?
1363
+
1364
+ # ========================================================================= #
1365
+ # === report_how_many_topics_are_available
1366
+ # ========================================================================= #
1367
+ def report_how_many_topics_are_available
1368
+ opne 'There are exactly '+
1369
+ simp(Studium.available_topics?.size.to_s)+
1370
+ ' topics available.'
1371
+ end
1372
+
1373
+ # ========================================================================= #
1374
+ # === may_we_show_the_topic?
1375
+ # ========================================================================= #
1376
+ def may_we_show_the_topic?
1377
+ @internal_hash[:may_we_show_the_topic]
1378
+ end; alias may_we_show_the_topic may_we_show_the_topic? # === may_we_show_the_topic
1379
+
1380
+ # ========================================================================= #
1381
+ # === set_may_we_show_the_topic
1382
+ # ========================================================================= #
1383
+ def set_may_we_show_the_topic(i = MAY_WE_SHOW_THE_TOPIC)
1384
+ @internal_hash[:may_we_show_the_topic] = i
1385
+ end; alias may_we_show_the_topic= set_may_we_show_the_topic # === may_we_show_the_topic=
1386
+ alias set_show_topic set_may_we_show_the_topic # === set_show_topic
1387
+
1388
+ # ========================================================================= #
1389
+ # === set_colour_for_questions
1390
+ # ========================================================================= #
1391
+ def set_colour_for_questions(i)
1392
+ @internal_hash[:colour_for_questions] = i.to_sym
1393
+ end
1394
+
1395
+ # ========================================================================= #
1396
+ # === set_colour_for_answers
1397
+ # ========================================================================= #
1398
+ def set_colour_for_answers(i)
1399
+ @internal_hash[:colour_for_answers] = i.to_sym
1400
+ end
1401
+
1402
+ # ========================================================================= #
1403
+ # === exam_question?
1404
+ # ========================================================================= #
1405
+ def exam_question?
1406
+ @exam_question.question?
1407
+ end; alias question? exam_question? # === question?
1408
+
1409
+ # ========================================================================= #
1410
+ # === show_the_last_topic
1411
+ #
1412
+ # Invocation example:
1413
+ #
1414
+ # qa --show-last-topic
1415
+ #
1416
+ # ========================================================================= #
1417
+ def show_the_last_topic(
1418
+ _ = Studium.file_last_topic?
1419
+ )
1420
+ if File.exist? _
1421
+ e "#{rev}The last topic was `"+
1422
+ simp(
1423
+ expand_topic(File.read(_).chomp)
1424
+ )+'`.'
1425
+ else
1426
+ opnn; no_file_exists_at(_.to_s)
1427
+ end
1428
+ end
1429
+
1430
+ # ========================================================================= #
1431
+ # === store_delay (store tag)
1432
+ #
1433
+ # This method will store/save the delay into a file.
1434
+ # ========================================================================= #
1435
+ def store_delay(i)
1436
+ Studium.save_this_delay_between_questions_and_answers(i)
1437
+ end
1438
+
1439
+ # ========================================================================= #
1440
+ # === load_file_rename_konsole_tab
1441
+ # ========================================================================= #
1442
+ def load_file_rename_konsole_tab
1443
+ YAML.load_file(FILE_RENAME_KONSOLE_TAB)
1444
+ end
1445
+
1446
+ # ========================================================================= #
1447
+ # === set_all_questions_from_the_topic_to_solved
1448
+ #
1449
+ # This will solve all questions from a given topic.
1450
+ #
1451
+ # Invocation example:
1452
+ #
1453
+ # qa ALL_SOLVED
1454
+ #
1455
+ # ========================================================================= #
1456
+ def set_all_questions_from_the_topic_to_solved
1457
+ if commandline?
1458
+ require 'studium/exams/solve_all_questions_from_this_topic.rb'
1459
+ this_topic = which_topic?
1460
+ e "#{rev}Setting all questions from the topic "\
1461
+ "#{sfancy(this_topic)} to solved."
1462
+ Studium::SolveAllQuestionsFromThisTopic.new(this_topic)
1463
+ end
1464
+ end
1465
+
1466
+ # ========================================================================= #
1467
+ # === report_this_error
1468
+ # ========================================================================= #
1469
+ def report_this_error(error = nil)
1470
+ opne 'We encountered an '+swarn('error')+
1471
+ '. The @index_position was probably '\
1472
+ 'out of range.'
1473
+ opne 'Feedbacking @line next:'
1474
+ pp line?
1475
+ opne "Feedbacking #{royalblue('the split position')} next:"
1476
+ pp split_position?
1477
+ if error
1478
+ pp error
1479
+ pp error.class
1480
+ end
1481
+ end
1482
+
1483
+ # ========================================================================= #
1484
+ # === report_how_many_registered_questions_are_available
1485
+ # ========================================================================= #
1486
+ def report_how_many_registered_questions_are_available(
1487
+ n_questions = ::Studium.n_questions_available?
1488
+ )
1489
+ opne "#{rev}There are #{simp(n_questions.to_s)} registered "\
1490
+ "questions available."
1491
+ end
1492
+
1493
+ # ========================================================================= #
1494
+ # === show_how_many_exam_questions_were_already_solved
1495
+ #
1496
+ # Use this method to show how many exam questions were already solved.
1497
+ #
1498
+ # To invoke this method, do:
1499
+ #
1500
+ # qa SOLVED?
1501
+ #
1502
+ # Or in code, do:
1503
+ #
1504
+ # Studium::Exams.report_how_many_exam_questions_were_already_solved
1505
+ #
1506
+ # ========================================================================= #
1507
+ def show_how_many_exam_questions_were_already_solved
1508
+ Studium.report_how_many_exam_questions_were_already_solved
1509
+ end
1510
+
1511
+ # ========================================================================= #
1512
+ # === report_whether_we_will_show_the_topic
1513
+ # ========================================================================= #
1514
+ def report_whether_we_will_show_the_topic
1515
+ opne 'Will we show the topic of the exams when '\
1516
+ 'asking a question: '+
1517
+ simp(VerboseTruth[may_we_show_the_topic?])
1518
+ end
1519
+
1520
+ # ========================================================================= #
1521
+ # === consider_warning_the_user_if_there_are_too_many_exams_registered
1522
+ #
1523
+ # The threshold value of n exam questions at maximum is at 1000
1524
+ # usually.
1525
+ # ========================================================================= #
1526
+ def consider_warning_the_user_if_there_are_too_many_exams_registered(
1527
+ threshold_value = THRESHOLD_VALUE_N_EXAMS_AT_MAXIMUM
1528
+ )
1529
+ if WARN_THE_USER_IF_THERE_ARE_TOO_MANY_QUESTIONS_REGISTERED_IN_AN_EXAM_TOPIC and
1530
+ # ===================================================================== #
1531
+ # Check if we have more questions than we are allowed to have.
1532
+ # ===================================================================== #
1533
+ (n_exam_questions? > threshold_value)
1534
+ e
1535
+ opne swarn('Do note that there are too many exam questions '\
1536
+ 'registered in the file:')
1537
+ e
1538
+ e " #{sfile(which_file?)}"
1539
+ e
1540
+ end
1541
+ end
1542
+
1543
+ # ========================================================================= #
1544
+ # === line?
1545
+ #
1546
+ # Delegate onto class ExamQuestion here.
1547
+ # ========================================================================= #
1548
+ def line?
1549
+ @exam_question.line?
1550
+ end
1551
+
1552
+ # ========================================================================= #
1553
+ # === delay?
1554
+ # ========================================================================= #
1555
+ def delay?
1556
+ @internal_hash[:delay]
1557
+ end; alias delay delay? # === delay
1558
+
1559
+ # ========================================================================= #
1560
+ # === report_the_default_topic_in_use
1561
+ #
1562
+ # This method will report the default topic in use. We must also check
1563
+ # whether the file in questions exists, before proceeding.
1564
+ #
1565
+ # To invoke this, do:
1566
+ #
1567
+ # qa --default-topic?
1568
+ #
1569
+ # ========================================================================= #
1570
+ def report_the_default_topic_in_use(
1571
+ this_file = "#{log_dir?}use_this_exam_topic.yml"
1572
+ )
1573
+ if File.exist? this_file
1574
+ topic = File.read(this_file).chomp
1575
+ e "The default topic in use is: #{simp(topic)}"
1576
+ else
1577
+ e "#{rev}No file exists at `#{sfile(this_file)}`. This "\
1578
+ "means that"
1579
+ e 'no default topic has been set.'
1580
+ e
1581
+ e 'If you wish to designate a default topic, use this invocation:'
1582
+ e
1583
+ e steelblue(' qa --set_default_topic=amg')
1584
+ e steelblue(' qa --set_default_topic=phys')
1585
+ e
1586
+ end
1587
+ end
1588
+
1589
+ # ========================================================================= #
1590
+ # === menu (menu tag)
1591
+ #
1592
+ # This is the main menu-interface of this class, the part of the code
1593
+ # where we take the commandline (if the user has done so) and evaluate
1594
+ # what is to be done.
1595
+ #
1596
+ # By default, we will assume that the user has not given any special
1597
+ # instructions, hence why the default argument is nil.
1598
+ #
1599
+ # Next we show some usage examples:
1600
+ #
1601
+ # qa "delay = 3.0"
1602
+ # qa delay?
1603
+ #
1604
+ # ========================================================================= #
1605
+ def menu(
1606
+ i = commandline_arguments?
1607
+ )
1608
+ if i.is_a? Array
1609
+ i.each {|entry| menu(entry) }
1610
+ else
1611
+ case i # case tag
1612
+ # ===================================================================== #
1613
+ # === qa amg1 --also-ask-from-solved-questions
1614
+ # === qa amg1 --full-pool
1615
+ # === qa amg1 --all-questions
1616
+ # === qa amg1 --everything
1617
+ #
1618
+ # This entry point allows us to pick a random question from ALL
1619
+ # questions of the given example theme, not only from the pool
1620
+ # that does not end with a trailing "[]".
1621
+ #
1622
+ # And yet another usage example:
1623
+ #
1624
+ # qa agrarmarkt --full
1625
+ #
1626
+ # ===================================================================== #
1627
+ when /^-?-?also(-|_| )?ask(-|_| )?from(-|_| )?solved(-|_| )?questions$/i,
1628
+ /^-?-?full(-|_| )?pool$/i,
1629
+ /^-?-?full$/i,
1630
+ /^-?-?all(-|_| )?questions$/i,
1631
+ /^-?-?everything$/i
1632
+ @internal_hash[:reject_lines_that_end_with_a_done_token] = false
1633
+ # ===================================================================== #
1634
+ # === qa --last-question?
1635
+ # ===================================================================== #
1636
+ when 'LAST?', # qa LAST_QUESTION?
1637
+ /^-?-?last$/,
1638
+ /^-?-?last(_|-)?question\??$/i
1639
+ show_last_question_asked
1640
+ exit_program
1641
+ # ===================================================================== #
1642
+ # === qa --total?
1643
+ # ===================================================================== #
1644
+ when /^-?-?TOTAL\??$/i # qa TOTAL?
1645
+ show_how_many_exam_questions_are_available
1646
+ exit_program
1647
+ # ===================================================================== #
1648
+ # === SHOW_ALL
1649
+ #
1650
+ # Invocation example:
1651
+ #
1652
+ # qa ethik --show-all
1653
+ #
1654
+ # ===================================================================== #
1655
+ when /^-?-?show(_|-)?all$/i,
1656
+ /^-?-?show(_|-)?everything$/i
1657
+ show_content_of_this_topic(topic?)
1658
+ exit
1659
+ # ===================================================================== #
1660
+ # === qa --n-topics
1661
+ # ===================================================================== #
1662
+ when /^-?-?n(_|-)?topics$/i # qa N_TOPICS
1663
+ report_how_many_topics_are_available
1664
+ exit_program
1665
+ # ===================================================================== #
1666
+ # === qa --show-statistics
1667
+ # ===================================================================== #
1668
+ when /^-?-?show(_|-| )?statistics/i
1669
+ show_statistics
1670
+ exit_program
1671
+ # ===================================================================== #
1672
+ # === qa --filesize?
1673
+ # ===================================================================== #
1674
+ when /^-?-?size\??/i,
1675
+ /^-?-?filesize\??/i
1676
+ show_filesize_of_all_exams
1677
+ exit
1678
+ # ===================================================================== #
1679
+ # === qa --show-topic?
1680
+ # ===================================================================== #
1681
+ when /^-?-?show(_|-| )?topic\??/i
1682
+ report_whether_we_will_show_the_topic
1683
+ exit_program
1684
+ # ===================================================================== #
1685
+ # === qa --upload_exams
1686
+ # ===================================================================== #
1687
+ when 'examtopics?',
1688
+ 'upload_exam_topics',
1689
+ /^upload_?exams/,
1690
+ 'uexams',
1691
+ 'uexam'
1692
+ Studium.upload_exam_questions { :be_verbose }
1693
+ # ===================================================================== #
1694
+ # === qa ALL_SOLVED
1695
+ #
1696
+ # This entry point will mark all questions from a particular topic
1697
+ # to "solved", that is, to have been answered already.
1698
+ #
1699
+ # Usage example:
1700
+ #
1701
+ # qa agrarmarkt --all-solved
1702
+ #
1703
+ # ===================================================================== #
1704
+ when /^-?-?all(-|_| )?solved$/i
1705
+ set_all_questions_from_the_topic_to_solved
1706
+ exit
1707
+ # ===================================================================== #
1708
+ # === qa --nquestions?
1709
+ # ===================================================================== #
1710
+ when /^-?-?n(_|-| )?questions\??$/i
1711
+ report_how_many_registered_questions_are_available
1712
+ exit
1713
+ # ===================================================================== #
1714
+ # === qa OPEN
1715
+ #
1716
+ # This entry point exists to edit this file here.
1717
+ # ===================================================================== #
1718
+ when 'OPEN',
1719
+ 'OPENALL',
1720
+ 'OALL',
1721
+ /^-?-?open$/
1722
+ open_this_file_in_editor
1723
+ exit_program
1724
+ # ===================================================================== #
1725
+ # === qa --ask_last_topic
1726
+ # ===================================================================== #
1727
+ when /^-?-?ask(_|-)?last(_|-)?topic$/
1728
+ target_file = "#{log_dir?}use_this_exam_topic.yml"
1729
+ if File.exist? target_file
1730
+ use_this_topic = YAML.load_file(
1731
+ target_file
1732
+ )
1733
+ set_use_this_topic(use_this_topic)
1734
+ else
1735
+ no_file_exists_at(target_file)
1736
+ end
1737
+ exit_program
1738
+ # ===================================================================== #
1739
+ # === qa ftp
1740
+ # ===================================================================== #
1741
+ when 'ftp',
1742
+ /^ftp(_|-)?upload$/
1743
+ Studium.upload_exam_questions { :be_verbose }
1744
+ exit_program
1745
+ # ===================================================================== #
1746
+ # === qa EDIT
1747
+ # ===================================================================== #
1748
+ when /^-?-?edit$/i,
1749
+ /^-?-?vim$/i
1750
+ edit_sanitize_topics_in_vim
1751
+ exit_program
1752
+ # ===================================================================== #
1753
+ # === qa --set_default_topic=phys
1754
+ # ===================================================================== #
1755
+ when /^-?-?set_default_topic=(.+)/,
1756
+ /^-?-?set-default-topic=(.+)/,
1757
+ /^-?-?topic=(.+)/,
1758
+ /^-?-?setdefaulttopic=(.+)/
1759
+ set_default_topic_for_the_gui($1.to_s)
1760
+ exit
1761
+ # ===================================================================== #
1762
+ # === qa --rename-tab?
1763
+ # ===================================================================== #
1764
+ when 'rename_tab?',
1765
+ '--rename-tab?',
1766
+ 'renametab',
1767
+ 'renametab?' # qa rename_tab?
1768
+ tell_whether_we_will_rename_the_kde_konsole_tab
1769
+ exit_program
1770
+ # ===================================================================== #
1771
+ # === qa --download-exam-topics
1772
+ # ===================================================================== #
1773
+ when /download_?exam_?topics/,
1774
+ /((_|-)+(_|-)+download(_|-)+exam(_|-)+topics)/,
1775
+ /^-?-?dexamtopics/
1776
+ download_exam_topics
1777
+ # ===================================================================== #
1778
+ # === qa --delay?
1779
+ # ===================================================================== #
1780
+ when 'del?',
1781
+ 'DELAY?',
1782
+ 'speed?', # qa delay?
1783
+ 'del',
1784
+ /^-?-?delay\??$/i
1785
+ report_the_delay
1786
+ exit_program(:no_newline)
1787
+ # ===================================================================== #
1788
+ # === qa LASTTOPIC
1789
+ # ===================================================================== #
1790
+ when /^-?-?last(_|-)?topic$/i,
1791
+ /^-?-?show(_|-)?last(_|-)?topic$/i,
1792
+ 'ltopic?'
1793
+ show_the_last_topic
1794
+ exit
1795
+ # ===================================================================== #
1796
+ # === qa --set-delay=2.8
1797
+ # ===================================================================== #
1798
+ when /^-?-?set(-|_| )?delay=(.+)/
1799
+ set_and_store_delay($2.to_s.dup)
1800
+ exit
1801
+ # ===================================================================== #
1802
+ # === qa --www
1803
+ # ===================================================================== #
1804
+ when /^-?-?www$/i
1805
+ generate_statistical_webpage
1806
+ exit
1807
+ # ===================================================================== #
1808
+ # === qa --finished?
1809
+ # ===================================================================== #
1810
+ when /^-?-?finished\??$/i
1811
+ show_all_finished_exam_topics
1812
+ exit
1813
+ # ===================================================================== #
1814
+ # === qa --help?
1815
+ # ===================================================================== #
1816
+ when 'HELP',
1817
+ 'help',
1818
+ '--help',
1819
+ '--hep',
1820
+ '--help?',
1821
+ 'help?'
1822
+ show_help_usage(:do_exit)
1823
+ # ===================================================================== #
1824
+ # === ptype --openlast
1825
+ # ===================================================================== #
1826
+ when /^OPEN(_|-)?LAST$/i,
1827
+ /^OLAST$/i
1828
+ open_the_last_file_via_your_editor
1829
+ exit
1830
+ # ===================================================================== #
1831
+ # === qa --german?
1832
+ # ===================================================================== #
1833
+ when 'SOLVED_GERMAN?',
1834
+ 'german',
1835
+ 'german?',
1836
+ 'in_german?',
1837
+ 'n_solved_in_german?',
1838
+ 'nsolved2?',
1839
+ 'n_german?',
1840
+ '--german?',
1841
+ /^-?-?solved(_|-)?in(_|-)?german$/i
1842
+ show_how_many_exam_questions_were_already_solved_in_german
1843
+ exit_program
1844
+ # ===================================================================== #
1845
+ # === qa --nsolved?
1846
+ # ===================================================================== #
1847
+ when /SOLVED/,
1848
+ 'N_SOLVED?',
1849
+ 'n_solved?',
1850
+ '--nsolved?',
1851
+ '--nsolved',
1852
+ 'nsolved',
1853
+ '--english?',
1854
+ '--english',
1855
+ 'english',
1856
+ 'english?'
1857
+ show_how_many_exam_questions_were_already_solved
1858
+ exit_program
1859
+ # ===================================================================== #
1860
+ # === qa --log-dir?
1861
+ #
1862
+ # This entry point would tell us that the log directory output is at
1863
+ # e. g. "/home/x/Temp/studium/".
1864
+ # ===================================================================== #
1865
+ when /^-?-?log\??$/i,
1866
+ /^-?-?log(-|_| )?dir\??$/i, # === qa log-dir?
1867
+ /^-?-?store(-|_| )?where\??$/i,
1868
+ /^-?-?dir\??$/i
1869
+ e "#{rev}The log directory can be found at: #{sdir(log_dir?)}"
1870
+ exit
1871
+ # ===================================================================== #
1872
+ # === qa --all-topics?
1873
+ #
1874
+ # Entry point for showing all available exam-topics:
1875
+ #
1876
+ # qa --show_topics
1877
+ #
1878
+ # ===================================================================== #
1879
+ when /^-?-?ALL/,
1880
+ /^-?-?TOPICS/,
1881
+ /^-?-?available(_|-)?topics\??$/i,
1882
+ /^-?-?topics\??$/i,
1883
+ /^-?-?show(_|-)?topics$/i,
1884
+ /^-?-?all(_|-)?topics$/i,
1885
+ /^-?-?ALL(-|_| )?TOPICS$/i,
1886
+ /^-?-?all(-|_| )?topics\??$/i,
1887
+ /^-?-?all(-|_| )?topics\??$/i,
1888
+ /^-?-?show(-|_| )?available(-|_| )?topics$/i,
1889
+ /^-?-?show(-|_| )?all(-|_| )?exam(-|_| )?topics$/i,
1890
+ 'detailed_topic'
1891
+ show_available_topics # This also includes an exit-step.
1892
+ exit
1893
+ # ===================================================================== #
1894
+ # === qa --default-topic?
1895
+ # ===================================================================== #
1896
+ when /^-?-?default(_|-)?topic\??$/i
1897
+ report_the_default_topic_in_use
1898
+ exit
1899
+ else
1900
+ if ::Studium.is_this_an_exam_topic?(i)
1901
+ set_exam_topic(i)
1902
+ end
1903
+ end
1904
+ end
1905
+ end
1906
+
1907
+ # ========================================================================= #
1908
+ # === show_all_finished_exam_topics
1909
+ #
1910
+ # To invoke this method, do:
1911
+ #
1912
+ # qa --finished?
1913
+ #
1914
+ # ========================================================================= #
1915
+ def show_all_finished_exam_topics
1916
+ stats = Studium::Statistics::ReportHowManyExamQuestionsWereAnswered.new {
1917
+ :do_not_show_the_result
1918
+ }.internal_dataset
1919
+ e "#{rev}The following topics are completely answered "\
1920
+ "(#{colourize_percentage('100%')} answered ratio)."
1921
+ array_finished_topics = []
1922
+ stats.select {|key, value|
1923
+ percentage = value[:percentage_of_questions_answered]
1924
+ if percentage == 100.0
1925
+ array_finished_topics << ::Studium.beautify_this_topic(key)
1926
+ end
1927
+ }
1928
+ e
1929
+ array_finished_topics.each {|topic|
1930
+ e " #{simp(topic)} is completely answered."
1931
+ }
1932
+ e
1933
+ end
1934
+
1935
+ # ========================================================================= #
1936
+ # === show_help_usage (help tag)
1937
+ #
1938
+ # We show help usage of this class here via this method. It is typically
1939
+ # used from the commandline.
1940
+ #
1941
+ # To show this help message, use this:
1942
+ #
1943
+ # qa --help
1944
+ #
1945
+ # ========================================================================= #
1946
+ def show_help_usage(
1947
+ then_exit = false
1948
+ )
1949
+ case then_exit
1950
+ # ======================================================================= #
1951
+ # === :do_exit
1952
+ # ======================================================================= #
1953
+ when :do_exit,
1954
+ :exit
1955
+ then_exit = true
1956
+ end
1957
+ opne "Currently the following extra commands can be issued:#{N}#{N}"
1958
+ lpad = ' ' * 4
1959
+ e "#{lpad}--set_default_topic= #{yellow(' Set a default topic.')}"
1960
+ e lpad+'TOPICS '+
1961
+ yellow(' List all available topics.')
1962
+ e lpad+'TOTAL '+
1963
+ yellow(" Show how many questions are known in total.")
1964
+ e lpad+'FINISHED '+
1965
+ yellow(' Show which topics are '\
1966
+ 'completely finished (100% answered).')
1967
+ e lpad+'EDIT '+
1968
+ yellow(' To edit the exam questions '\
1969
+ 'file, via vim.')
1970
+ e lpad+'LAST_TOPIC '+
1971
+ yellow(' Show the last topic used.')
1972
+ e lpad+'BLOCK '+
1973
+ yellow(' List all questions that '\
1974
+ 'were already answered for a given section.')
1975
+ e lpad+'OPEN '+
1976
+ yellow(' Open this file here in an editor.')
1977
+ e lpad+'--download-exam-topics '+
1978
+ yellow(' Download the exam topics.')
1979
+ e lpad+'--all-questions '+
1980
+ yellow(' Ask all questions, including those marked '\
1981
+ 'with a trailing "[]".')
1982
+ e lpad+'delay? '+
1983
+ yellow(' show the default delay.')
1984
+ e lpad+"'delay = 5' "+
1985
+ yellow(' to set a new delay to 5 seconds.')
1986
+ e lpad+"'set-delay = 5' "+
1987
+ yellow(' to set a new delay '\
1988
+ 'to 5 seconds. (as ^^^ above)')
1989
+ if is_on_roebe? # Show more options only on my system.
1990
+ e lpad+'rename_tab? '+
1991
+ yellow(' whether to rename the KDE konsole tab or not.')
1992
+ e lpad+'rename_tab: true'+
1993
+ yellow(' enable renaming of the KDE konsole tab.')
1994
+ e lpad+'rename_tab: false'+
1995
+ yellow(' disable rename of the KDE konsole tab.')
1996
+ end
1997
+ e
1998
+ exit if then_exit
1999
+ end
2000
+
2001
+ # ========================================================================= #
2002
+ # === report_the_delay
2003
+ # ========================================================================= #
2004
+ def report_the_delay
2005
+ e "#{rev}The delay is set to: #{sfancy(delay?.to_s)}"
2006
+ end
2007
+
2008
+ # ========================================================================= #
2009
+ # === set_and_store_delay
2010
+ #
2011
+ # Combine two methods in one here.
2012
+ # ========================================================================= #
2013
+ def set_and_store_delay(i)
2014
+ set_delay(i)
2015
+ store_delay(i)
2016
+ end
2017
+
2018
+ # ========================================================================= #
2019
+ # === read_delay_from_file (load delay)
2020
+ #
2021
+ # Use this method here, read_delay_from_file(), to read in the
2022
+ # default delay from a stored file.
2023
+ # ========================================================================= #
2024
+ def read_delay_from_file
2025
+ if File.exist? DELAY_CONSTANT_STORED_HERE
2026
+ _ = YAML.load_file(DELAY_CONSTANT_STORED_HERE)
2027
+ result = _['delay']
2028
+ else # Else the file does not exist, so we use the default delay.
2029
+ result = DEFAULT_DELAY
2030
+ end
2031
+ return result
2032
+ end
2033
+
2034
+ # ========================================================================= #
2035
+ # === sanitize_the_obtained_dataset (sanitized tag)
2036
+ #
2037
+ # This method exists primarily to remove all trailing "\n", and then
2038
+ # remove all [] entries, as well as show how many exam questions are
2039
+ # in that given file.
2040
+ # ========================================================================= #
2041
+ def sanitize_the_obtained_dataset
2042
+ dataset = dataset?.map {|entry| entry.strip }
2043
+ set_dataset(dataset)
2044
+ # ======================================================================= #
2045
+ # === :n_exam_questions_in_total
2046
+ #
2047
+ # Keep a record of the total number of exam questions here.
2048
+ # ======================================================================= #
2049
+ @internal_hash[:n_exam_questions_in_total] = dataset.size
2050
+ _ = dataset.reject {|line|
2051
+ line.rstrip.end_with? '[]'
2052
+ }
2053
+ if _ # Keep track of the unanswered exam questions here.
2054
+ set_exam_pool(_)
2055
+ # ===================================================================== #
2056
+ # === :n_exam_questions_unanswered
2057
+ # ===================================================================== #
2058
+ @internal_hash[:n_exam_questions_unanswered] = _.size
2059
+ # ===================================================================== #
2060
+ # === :n_exam_questions_answered
2061
+ # ===================================================================== #
2062
+ @internal_hash[:n_exam_questions_answered] = (
2063
+ @internal_hash[:n_exam_questions_in_total] - _.size
2064
+ )
2065
+ end
2066
+ end
2067
+
2068
+ # ========================================================================= #
2069
+ # === fancy_cliner
2070
+ #
2071
+ # Since as of April 2022 this method can also optionally display some
2072
+ # content. If this is the case then said content will be padded
2073
+ # via '*'.
2074
+ # ========================================================================= #
2075
+ def fancy_cliner(
2076
+ optional_content_to_be_displayed = nil,
2077
+ use_this_as_the_separator_token = separator_token_to_be_used?
2078
+ )
2079
+ print seagreen('') # Always reset the colour here first.
2080
+ if optional_content_to_be_displayed
2081
+ e mediumaquamarine(use_this_as_the_separator_token * 3)+' '+
2082
+ forestgreen( # or lightskyblue
2083
+ optional_content_to_be_displayed
2084
+ )+
2085
+ ' '+
2086
+ mediumaquamarine(
2087
+ use_this_as_the_separator_token * (75 - optional_content_to_be_displayed.size)
2088
+ )
2089
+ else
2090
+ cliner(use_this_as_the_separator_token, :mediumaquamarine)
2091
+ end
2092
+ end
2093
+
2094
+ # ========================================================================= #
2095
+ # === determine_the_exam_topic
2096
+ #
2097
+ # This variant also stores the exam-topic into a file, unless we are
2098
+ # using the www-variant of this class.
2099
+ # ========================================================================= #
2100
+ def determine_the_exam_topic
2101
+ _ = first_non_hyphen_argument?
2102
+ set_exam_topic_to_use(
2103
+ find_corresponding_exam_topic(_)
2104
+ )
2105
+ store_last_topic_into_file unless in_www_mode?
2106
+ end; alias determine_the_topic determine_the_exam_topic # === determine_the_topic
2107
+
2108
+ # ========================================================================= #
2109
+ # === set_topic_to_use
2110
+ #
2111
+ # This method has to store the expanded topic name, so that something
2112
+ # like "bioanalytik" is actually turned into
2113
+ # "bioanalytik_und_biosensoren". The method that handles this part is
2114
+ # Studium.find_corresponding_exam_topic(). Usage example for this:
2115
+ #
2116
+ # x = Studium.find_corresponding_exam_topic('bioanalytik') # => "bioanalytik_und_biosensoren"
2117
+ #
2118
+ # Whenever a topic is set through this method, this will also be stored
2119
+ # into a file. This then allows us to query what the last topic was, e.
2120
+ # g. via "qa --last_topic?".
2121
+ # ========================================================================= #
2122
+ def set_topic_to_use(
2123
+ i = first_non_hyphen_argument?
2124
+ )
2125
+ i = i.first if i.is_a? Array
2126
+ # ======================================================================= #
2127
+ # === Handle Hashes
2128
+ #
2129
+ # If a Hash is given then we will try to find a specific key in that
2130
+ # Hash.
2131
+ # ======================================================================= #
2132
+ if i.is_a?(Hash) and i.has_key?(:use_this_topic)
2133
+ i = i[:use_this_topic]
2134
+ end
2135
+ case i
2136
+ # ======================================================================= #
2137
+ # === :random
2138
+ #
2139
+ # We fetch a random topic via this entry-point.
2140
+ # ======================================================================= #
2141
+ when :random,
2142
+ :random_topic,
2143
+ :default,
2144
+ 'fetch_a_random_topic',
2145
+ 'random_topic',
2146
+ 'random',
2147
+ 'rand',
2148
+ '',
2149
+ nil
2150
+ i = Studium.random_exam_topic
2151
+ # ======================================================================= #
2152
+ # === molbio
2153
+ #
2154
+ # This entry point is special.
2155
+ # ======================================================================= #
2156
+ when 'molbio',
2157
+ 'molekularbiologie',
2158
+ 'molbio?'
2159
+ i = 'amg|amg2|genex1|gentech1|gentech2|pcr'
2160
+ # ======================================================================= #
2161
+ # === OLAST
2162
+ #
2163
+ # Invocation example:
2164
+ #
2165
+ # qa olast
2166
+ #
2167
+ # ======================================================================= #
2168
+ when /^qlast$/i,
2169
+ /^olast$/i # === olast tag
2170
+ _ = Studium.file_last_topic?
2171
+ if File.exist? _
2172
+ i = File.read(_).strip
2173
+ else
2174
+ opnn; no_file_exists_at(_)
2175
+ exit
2176
+ end
2177
+ end
2178
+ i = i.to_s.dup # Work with a non-frozen String past this point.
2179
+ # ======================================================================= #
2180
+ # If the input has a '|', we assume that the user wants to randomly
2181
+ # pick one entry.
2182
+ # ======================================================================= #
2183
+ if i.include? '|'
2184
+ i = i.split('|').shuffle
2185
+ end
2186
+ i.tr!(' ','_') if i.include? ' '
2187
+ i.downcase! # Convention is to store the file downcased.
2188
+ # ======================================================================= #
2189
+ # Before we do the real assignment, we will sanitize this through
2190
+ # the Studium.find_corresponding_exam_topic "filter".
2191
+ # ======================================================================= #
2192
+ if Studium.is_this_a_registered_exam_topic?(i)
2193
+ i = Studium.find_corresponding_exam_topic(i)
2194
+ else
2195
+ opne "Not a registered exam topic: #{i}" if be_verbose?
2196
+ end
2197
+ @internal_hash[:topic_to_use] = i
2198
+ # ======================================================================= #
2199
+ # Next we will store the topic into a file, unless we are in www-mode.
2200
+ # We may have to lift this restriction eventually, though.
2201
+ # ======================================================================= #
2202
+ unless in_www_mode?
2203
+ store_last_topic_into_file(i)
2204
+ end
2205
+ end; alias set_exam_topic set_topic_to_use # === set_exam_topic
2206
+ alias set_exam_topic_to_use set_topic_to_use # === set_exam_topic_to_use
2207
+ alias set_this_topic set_topic_to_use # === set_this_topic
2208
+
2209
+ # ========================================================================= #
2210
+ # === try_to_read_in_the_dataset_from_the_corresponding_exam_file
2211
+ # ========================================================================= #
2212
+ def try_to_read_in_the_dataset_from_the_corresponding_exam_file(
2213
+ _ = exam_topics_directory?+
2214
+ topic?.to_s
2215
+ )
2216
+ if File.exist? _
2217
+ # ===================================================================== #
2218
+ # Keep track of where the exam-file can be found.
2219
+ # ===================================================================== #
2220
+ set_exam_file(_)
2221
+ dataset = read_in_exam_dataset_from_this_file(_)
2222
+ set_dataset_from_the_file(dataset)
2223
+ else
2224
+ report_file_does_not_exist(_)
2225
+ end
2226
+ end
2227
+
2228
+ # ========================================================================= #
2229
+ # === ask_the_question_then_sleep_then_reveal_the_answer_to_that_question
2230
+ # ========================================================================= #
2231
+ def ask_the_question_then_sleep_then_reveal_the_answer_to_that_question
2232
+ # ======================================================================= #
2233
+ # First warn the user if there are too many exams registered. This
2234
+ # should be shown after the topic has been optionally displayed.
2235
+ # Afterwards we will begin to ask the exam-question at hand.
2236
+ # ======================================================================= #
2237
+ consider_warning_the_user_if_there_are_too_many_exams_registered
2238
+ # Store it into @internal_hash[:dataset_from_the_file].
2239
+ store_relevant_information_pertaining_to_the_last_exam_question_asked
2240
+ # ======================================================================= #
2241
+ # First, handle the commandline situation:
2242
+ # ======================================================================= #
2243
+ if commandline?
2244
+ consider_renaming_konsole_tab # Consider renaming the konsole tab first.
2245
+ print return_either_grey_or_the_custom_colour_for_questions
2246
+ # ===================================================================== #
2247
+ # === Show the topic if the user requested us to do so. Since as of
2248
+ # April 2022 this is now embedded into the cliner-result.
2249
+ # ===================================================================== #
2250
+ if may_we_show_the_topic?
2251
+ fancy_cliner(
2252
+ Studium.find_corresponding_exam_title(exam_title?, be_verbose?)
2253
+ )
2254
+ e
2255
+ else
2256
+ fancy_cliner
2257
+ end
2258
+ end
2259
+ do_ask_the_question # Ask the exam question here.
2260
+ sleep_default_delay
2261
+ determine_whether_there_are_numbers_in_parens_in_the_answer
2262
+ do_reveal_the_answer
2263
+ end; alias ask_question_then_show_the_answer_after_a_delay ask_the_question_then_sleep_then_reveal_the_answer_to_that_question # === ask_question_then_show_the_answer_after_a_delay
2264
+ alias do_ask_a_random_question_before_showing_the_answer ask_the_question_then_sleep_then_reveal_the_answer_to_that_question # === ask_question_then_show_the_answer_after_a_delay
2265
+ alias show_question_then_sleep_then_show_answer ask_the_question_then_sleep_then_reveal_the_answer_to_that_question # === show_question_then_sleep_then_show_answer
2266
+ alias ask_sleep_show ask_the_question_then_sleep_then_reveal_the_answer_to_that_question # === ask_sleep_show
2267
+ alias ask_the_question_then_reveal_the_answer ask_the_question_then_sleep_then_reveal_the_answer_to_that_question # === ask_the_question_then_reveal_the_answer
2268
+
2269
+ # ========================================================================= #
2270
+ # === determine_whether_there_are_numbers_in_parens_in_the_answer
2271
+ # ========================================================================= #
2272
+ def determine_whether_there_are_numbers_in_parens_in_the_answer
2273
+ _ = exam_answer?
2274
+ if _.include?('(2)') and _.include?('(1)') # We also have to check for (1)
2275
+ # ===================================================================== #
2276
+ # at the same time, because some answers to exam questions contain
2277
+ # just a "(2)" without a corresponding "(1)".
2278
+ # ===================================================================== #
2279
+ @internal_hash[:numbers_in_parens] = true
2280
+ end
2281
+ end
2282
+
2283
+ # ========================================================================= #
2284
+ # === n_questions_available?
2285
+ #
2286
+ # Return how many questions are available in the given dataset at hand.
2287
+ # ========================================================================= #
2288
+ def n_questions_available?
2289
+ @internal_hash[:n_exam_questions_in_total]
2290
+ end; alias n_exam_questions? n_questions_available? # === n_exam_questions?
2291
+ alias n_questions? n_questions_available? # === n_questions?
2292
+
2293
+ # ========================================================================= #
2294
+ # === ensure_that_the_directory_for_the_daily_questions_exists
2295
+ # ========================================================================= #
2296
+ def ensure_that_the_directory_for_the_daily_questions_exists
2297
+ _ = File.dirname(FILE_DAILY_QUESTIONS_SOLVED)
2298
+ unless File.directory? _
2299
+ mkdir(_)
2300
+ end
2301
+ end
2302
+
2303
+ # ========================================================================= #
2304
+ # === do_not_assume_numbers_in_parens
2305
+ # ========================================================================= #
2306
+ def do_not_assume_numbers_in_parens
2307
+ @internal_hash[:numbers_in_parens] = false # Reset it here.
2308
+ end
2309
+
2310
+ # ========================================================================= #
2311
+ # === invoke_all_the_necessary_steps_before_the_question_is_asked
2312
+ # ========================================================================= #
2313
+ def invoke_all_the_necessary_steps_before_the_question_is_asked
2314
+ ensure_that_the_directory_for_the_daily_questions_exists
2315
+ do_not_assume_numbers_in_parens
2316
+ determine_the_exam_topic
2317
+ try_to_read_in_the_dataset_from_the_corresponding_exam_file
2318
+ sanitize_the_obtained_dataset
2319
+ random_line = pick_a_random_line_from_the_obtained_dataset
2320
+ parse_the_random_line_from_the_obtained_dataset(random_line)
2321
+ # sample_line = @internal_hash[:dataset_from_the_file].sample
2322
+ # parse_the_random_line_from_the_obtained_dataset(sample_line)
2323
+ end; alias initial_steps invoke_all_the_necessary_steps_before_the_question_is_asked # === initial_steps
2324
+ alias initialize_the_dataset invoke_all_the_necessary_steps_before_the_question_is_asked # === initialize_the_dataset
2325
+
2326
+ # ========================================================================= #
2327
+ # === pick_a_random_line_from_the_obtained_dataset
2328
+ # ========================================================================= #
2329
+ def pick_a_random_line_from_the_obtained_dataset
2330
+ _ = dataset_from_the_file?.reject {|line|
2331
+ line.end_with?(' []')
2332
+ } # Reject already solved exam questions.
2333
+ use_this_sample = _.sample
2334
+ set_exam_question_line(use_this_sample)
2335
+ try_to_save_the_line(use_this_sample)
2336
+ return use_this_sample
2337
+ end
2338
+
2339
+ # ========================================================================= #
2340
+ # === show_statistics
2341
+ #
2342
+ # To invoke this method from the commandline, try:
2343
+ #
2344
+ # qa --show-statistics
2345
+ #
2346
+ # ========================================================================= #
2347
+ def show_statistics(
2348
+ dataset = dataset?
2349
+ )
2350
+ unless in_www_mode?
2351
+ n_questions = n_questions_available?
2352
+ n_answered = n_questions_already_answered?
2353
+ percentage = (n_answered.to_f * 100) / n_questions
2354
+ result = olivedrab(n_questions.to_s)+
2355
+ grey(' questions available, ')+
2356
+ mediumaquamarine(n_answered.to_s)+
2357
+ grey(' (')+
2358
+ colourize_percentage(percentage.round(2).to_s+'%')+
2359
+ grey(") already answered.#{N}")
2360
+ # ===================================================================== #
2361
+ # Also add how many questions in absolute numbers have to be answered
2362
+ # still.
2363
+ # ===================================================================== #
2364
+ padded_amount_of_questions_answered = (n_questions - n_answered).to_s
2365
+ padded_amount_of_questions_answered =
2366
+ padded_amount_of_questions_answered.rjust(n_questions.to_s.size)
2367
+ result << "#{crimson(padded_amount_of_questions_answered)} "\
2368
+ "#{grey('questions could still be answered. Topic: ')}"\
2369
+ "#{olive(return_the_full_expanded_exam_title)}"\
2370
+ "#{grey('.')}#{rev}"
2371
+ e result
2372
+ end
2373
+ end; alias report_statistics show_statistics # === report_statistics
2374
+
2375
+ # ========================================================================= #
2376
+ # === have_all_the_exam_questions_for_this_topic_been_answered_already?
2377
+ # ========================================================================= #
2378
+ def have_all_the_exam_questions_for_this_topic_been_answered_already?(i = topic?)
2379
+ _ = dataset?.reject {|line| line.end_with?('[]') }.size
2380
+ _ == 0
2381
+ end
2382
+
2383
+ require 'studium/logging/store_last_question_asked_into_file.rb'
2384
+ # ========================================================================= #
2385
+ # === do_log_related_and_backup_related_actions
2386
+ #
2387
+ # This method will backup files and similar activities.
2388
+ #
2389
+ # Note that the method exam_file?() will return a String such as:
2390
+ #
2391
+ # "/home/x/programming/ruby/src/studium/lib/studium/exam_topics/protein_engineering"
2392
+ #
2393
+ # ========================================================================= #
2394
+ def do_log_related_and_backup_related_actions
2395
+ unless Studium.is_in_www_mode?
2396
+ Studium.backup_this_exam_file(exam_file?) # { :be_verbose }
2397
+ hash = {} # Build up our data structure here, as a Hash.
2398
+ hash[:question_was_asked_when] = Time.now
2399
+ hash[:question_full_line] = line?
2400
+ Studium::Log::StoreLastQuestionAskedIntoFile.new(hash) # { :be_verbose }
2401
+ append_into_onto_daily_exam_questions_file
2402
+ end
2403
+ end
2404
+
2405
+ # ========================================================================= #
2406
+ # === store_relevant_information_pertaining_to_the_last_exam_question_asked
2407
+ # ========================================================================= #
2408
+ def store_relevant_information_pertaining_to_the_last_exam_question_asked
2409
+ _ = studium_log_dir?
2410
+ mkdir(
2411
+ File.dirname(Studium.file_last_topic?)
2412
+ )
2413
+ # ======================================================================= #
2414
+ # Store the last exam topic first:
2415
+ # ======================================================================= #
2416
+ write_what_into(last_topic?, Studium.file_last_topic?)
2417
+ target_directory = "#{_}information_pertaining_to_the_last_exam_question_asked/"
2418
+ mkdir(target_directory) unless File.directory?(target_directory)
2419
+ # ======================================================================= #
2420
+ # Store the last exam-question-answer next:
2421
+ # ======================================================================= #
2422
+ last_exam_question_answer = Studium.file_last_question_asked?
2423
+ what = line?
2424
+ into = last_exam_question_answer
2425
+ write_what_into(what, into)
2426
+ # ======================================================================= #
2427
+ # Store the last exam-question time next:
2428
+ # ======================================================================= #
2429
+ last_exam_question_answer_time = target_directory+'last_exam_question_answer_time.yml'
2430
+ what = YAML.dump(Time.now)
2431
+ into = last_exam_question_answer_time
2432
+ write_what_into(what, into)
2433
+ # ======================================================================= #
2434
+ # Store the last exam-question next - this is just the question-part:
2435
+ # ======================================================================= #
2436
+ last_exam_question = "#{target_directory}last_exam_question.md"
2437
+ what = exam_question?
2438
+ into = last_exam_question
2439
+ write_what_into(what, into)
2440
+ end
2441
+
2442
+ # ========================================================================= #
2443
+ # === parse_the_random_line_from_the_obtained_dataset
2444
+ # ========================================================================= #
2445
+ def parse_the_random_line_from_the_obtained_dataset(i)
2446
+ @exam_question.parse(i)
2447
+ end
2448
+
2449
+ # ========================================================================= #
2450
+ # === pick_this_question_answer
2451
+ # ========================================================================= #
2452
+ def pick_this_question_answer(i)
2453
+ set_exam_topic('Custom exam topic')
2454
+ parse_the_random_line_from_the_obtained_dataset(i)
2455
+ ask_the_question_then_sleep_then_reveal_the_answer_to_that_question
2456
+ end
2457
+
2458
+ # ========================================================================= #
2459
+ # === set_custom_colours
2460
+ #
2461
+ # This setter is, since as of January 2022, just calling two methods now.
2462
+ # This was simpler to maintain than using another ad-hoc Hash.
2463
+ #
2464
+ # Valid keys for the colours should be, for instance, "colour_for_questions"
2465
+ # or "colour_for_answers".
2466
+ # ========================================================================= #
2467
+ def set_custom_colours(i)
2468
+ if i.is_a?(String) and i.include?('|')
2469
+ # ===================================================================== #
2470
+ # Allow custom input, as String, so users can override this.
2471
+ # ===================================================================== #
2472
+ splitted = i.split('|')
2473
+ set_colour_for_questions(splitted.first)
2474
+ set_colour_for_answers(splitted.last)
2475
+ end
2476
+ end
2477
+
2478
+ # ========================================================================= #
2479
+ # === do_ask_the_question (question tag, ask tag)
2480
+ #
2481
+ # Simply display the question via this method.
2482
+ # ========================================================================= #
2483
+ def do_ask_the_question(
2484
+ this_question = exam_question?,
2485
+ use_this_colour = colour_for_questions?
2486
+ )
2487
+ this_question = this_question.dup if this_question
2488
+ # ======================================================================= #
2489
+ # First, handle the commandline situation:
2490
+ # ======================================================================= #
2491
+ if commandline?
2492
+ # ===================================================================== #
2493
+ # === Handle underlined text next
2494
+ # ===================================================================== #
2495
+ if line_contains_underline_token?(this_question) and use_colours?
2496
+ # =================================================================== #
2497
+ # Colourize <ud> for underline next:
2498
+ # =================================================================== #
2499
+ this_question = replace_underline_token_with_default_colour(this_question, use_this_colour)
2500
+ end
2501
+ # ===================================================================== #
2502
+ # === Handle italic text next
2503
+ # ===================================================================== #
2504
+ if line_contains_italic_token?(this_question) and use_colours?
2505
+ # =================================================================== #
2506
+ # Colourize <i> for italic next:
2507
+ # =================================================================== #
2508
+ this_question = replace_italic_token_with_default_colour(this_question, use_this_colour)
2509
+ end
2510
+ # ===================================================================== #
2511
+ # === Colourize words in quotes
2512
+ #
2513
+ # Next, consider colourizing all answers that have at the least 2
2514
+ # '"' characters. These will be colourized.
2515
+ # ===================================================================== #
2516
+ if EMPHASIZE_WORDS_IN_QUOTES_IN_A_GIVEN_ANSWER
2517
+ if use_colours? and commandline? and (this_question.count('"') > 1)
2518
+ use_this_regex = /"(.+?\s*.*?)"/ # See: http://rubular.com/r/6WK5NjMJld
2519
+ use_this_colour = ::Colours.send(colour_for_answers?) { :omit_end }
2520
+ this_question.gsub!(
2521
+ use_this_regex,
2522
+ '"'+steelblue('\1'.delete(N))+
2523
+ use_this_colour+'"'
2524
+ )
2525
+ end
2526
+ end
2527
+ # ===================================================================== #
2528
+ # Output the result finally, by making use of the toplevel method
2529
+ # Colours.replace_number_words_with_the_corresponding_html_colour().
2530
+ # ===================================================================== #
2531
+ _ = ::Colours.replace_number_words_with_the_corresponding_html_colour(
2532
+ DEFAULT_COLOUR_AS_ESCAPE_SEQUENCE+
2533
+ this_question,
2534
+ @internal_hash[:use_these_colours]
2535
+ )
2536
+ e ::Colours.fancy_parse(_, use_this_colour)
2537
+ e if may_we_show_the_topic?
2538
+ fancy_cliner
2539
+ else # else tag
2540
+ # ===================================================================== #
2541
+ # === WWW mode
2542
+ #
2543
+ # Else we assume that this class is used on the web.
2544
+ # ===================================================================== #
2545
+ result = ''.dup
2546
+ result << "#{this_question}#{N}<br><br>"
2547
+ @internal_hash[:result_for_www] = result
2548
+ # ===================================================================== #
2549
+ # Next, show the question, unless we operate in WWW mode.
2550
+ # ===================================================================== #
2551
+ e result unless www_mode?
2552
+ end
2553
+ e
2554
+ end; alias ask_the_exam_question do_ask_the_question # === ask_the_exam_question
2555
+ alias ask_the_question do_ask_the_question # === ask_the_question
2556
+ alias ask_this_question do_ask_the_question # === ask_this_question
2557
+ alias show_question do_ask_the_question # === show_question
2558
+
2559
+ # ========================================================================= #
2560
+ # === store_last_topic_into_file
2561
+ #
2562
+ # This method will store the last-exam-topic into a local file.
2563
+ #
2564
+ # By default we will not report this activity.
2565
+ # ========================================================================= #
2566
+ def store_last_topic_into_file(
2567
+ what = topic?,
2568
+ into = Studium.file_last_topic? # This would store into: "/root/Studium/last_topic.md"
2569
+ )
2570
+ base_dir = File.dirname(into)
2571
+ unless File.directory?(base_dir)
2572
+ mkdir(base_dir) # This is a directory such as "/home/x/Temp/studium/last_topic/".
2573
+ end
2574
+ write_what_into(what, into)
2575
+ end
2576
+
2577
+ # ========================================================================= #
2578
+ # === run (run tag)
2579
+ # ========================================================================= #
2580
+ def run
2581
+ menu_on_the_commandline_as_a_string
2582
+ menu
2583
+ invoke_all_the_necessary_steps_before_the_question_is_asked
2584
+ if have_all_the_exam_questions_for_this_topic_been_answered_already?(topic?)
2585
+ notify_the_user_that_all_questions_have_been_answered_already
2586
+ else
2587
+ ask_the_question_then_sleep_then_reveal_the_answer_to_that_question
2588
+ # ===================================================================== #
2589
+ # After the answer has been shown, it is time to display some statistics.
2590
+ # ===================================================================== #
2591
+ show_statistics
2592
+ do_log_related_and_backup_related_actions
2593
+ # ===================================================================== #
2594
+ # Register the last file that was modified.
2595
+ # ===================================================================== #
2596
+ register_last_modified_file
2597
+ end
2598
+ end
2599
+
2600
+ end
2601
+
2602
+ # =========================================================================== #
2603
+ # === Studium::Exams.question_answer
2604
+ # =========================================================================== #
2605
+ def self.question_answer(
2606
+ topic = 'random_topic',
2607
+ run_already = true,
2608
+ &block
2609
+ )
2610
+ Studium::Exams::ExamQuestion.new(topic, run_already, &block)
2611
+ end
2612
+
2613
+ # =========================================================================== #
2614
+ # === Studium::Exams[]
2615
+ #
2616
+ # This will simply use AskQuestion as defined above.
2617
+ #
2618
+ # Usage examples, including aliases:
2619
+ #
2620
+ # amg = Studium::Exams['amg']
2621
+ # qa = Exams.question_answer('yo', :dont_run_yet)
2622
+ #
2623
+ # =========================================================================== #
2624
+ def self.[](i, run_already = true)
2625
+ Studium::Exams::ExamQuestion.new(i, run_already)
2626
+ end; self.instance_eval { alias ask_question [] } # === ::Studium::Exams.ask_question
2627
+
2628
+ end
2629
+
2630
+ # =========================================================================== #
2631
+ # === Studium.ask_question
2632
+ #
2633
+ # This provides an easier API to ask a question.
2634
+ #
2635
+ # Usage example:
2636
+ #
2637
+ # x = Studium.ask_question 'amg'
2638
+ # y = Studium.ask_question('amg2') { :do_not_run_yet }
2639
+ #
2640
+ # =========================================================================== #
2641
+ def self.ask_question(
2642
+ i = ARGV,
2643
+ run_already = true,
2644
+ &block
2645
+ )
2646
+ Studium::Exams::ExamQuestion.new(i, run_already, &block)
2647
+ end; self.instance_eval { alias question_answer ask_question } # === Studium.question_answer
2648
+ self.instance_eval { alias new_exam ask_question } # === Studium.new_exam
2649
+ self.instance_eval { alias ask_question ask_question } # === Studium.ask_question
2650
+ self.instance_eval { alias ask_exam_question ask_question } # === Studium.ask_exam_question
2651
+
2652
+ # =========================================================================== #
2653
+ # === Studium.random_question
2654
+ #
2655
+ # This method will ask a random exam question.
2656
+ # =========================================================================== #
2657
+ def self.random_question
2658
+ ask_question(:random)
2659
+ end
2660
+
2661
+ # =========================================================================== #
2662
+ # === Studium.delay_for_exam_questions?
2663
+ # =========================================================================== #
2664
+ def self.delay_for_exam_questions?
2665
+ ::Studium::DEFAULT_DELAY
2666
+ end
2667
+
2668
+ # =========================================================================== #
2669
+ # === Studium.random_exam_topic?
2670
+ #
2671
+ # This method will return a random exam topic when it is called.
2672
+ #
2673
+ # Usage examples:
2674
+ #
2675
+ # Studium.random_exam_topic? # => "epigenetik"
2676
+ # Studium.random_exam_topic? # => "abfall_als_ressource"
2677
+ # Studium.random_exam_topic? # => "embryologie_und_entwicklung"
2678
+ #
2679
+ # =========================================================================== #
2680
+ def self.random_exam_topic?
2681
+ ::Studium::Exams.all_topics_as_short_name.sort.sample
2682
+ end
2683
+
2684
+ # =========================================================================== #
2685
+ # === Studium.return_question_answer_as_array
2686
+ #
2687
+ # This method will return the question-answer combination, as an Array.
2688
+ #
2689
+ # It will not make use of any colours; the reason for this is because
2690
+ # when this method was added as of the 13.04.2019, it was to be used
2691
+ # primarily on the www.
2692
+ #
2693
+ # If the input is a String and contains '- ' then we assume that we do
2694
+ # NOT want to find a specific topic. Instead we will use the given
2695
+ # input as exam-question + exam-answer as such.
2696
+ #
2697
+ # Invocation examples:
2698
+ #
2699
+ # x = Studium.return_question_answer_as_array('amg1')
2700
+ # x = Studium.return_question_answer_as_array('biotech1')
2701
+ # x = Studium.return_question_answer_as_array(:biotech2)
2702
+ # x = Studium.return_question_answer_as_array('- In Ruby: <one>Bundler</one> likes ... ? Gemfile.lock.')
2703
+ #
2704
+ # =========================================================================== #
2705
+ def self.return_question_answer_as_array(
2706
+ topic = 'random_topic',
2707
+ &block
2708
+ )
2709
+ _ = ::Studium::Exams::AskExamQuestion.new(topic, :do_not_run_yet, &block)
2710
+ if topic.is_a?(String) and topic.include?('-')
2711
+ _.set_exam_question_line_and_then_parse_that_line(topic)
2712
+ else
2713
+ _.invoke_all_the_necessary_steps_before_the_question_is_asked
2714
+ end
2715
+ _.disable_colours
2716
+ # ========================================================================= #
2717
+ # We will return the proper Array next:
2718
+ # ========================================================================= #
2719
+ [
2720
+ _.question?,
2721
+ _.answer?.to_s.delete("\n").squeeze(' ')
2722
+ ]
2723
+ end; self.instance_eval { alias determine_question_answer_from_this return_question_answer_as_array } # === Studium.determine_question_answer_from_this
2724
+ self.instance_eval { alias determine_question_answer_from_this_line return_question_answer_as_array } # === Studium.determine_question_answer_from_this_line
2725
+ self.instance_eval { alias return_question_answer_from_this_exam_topic return_question_answer_as_array } # === Studium.return_question_answer_from_this_exam_topic
2726
+
2727
+ # =========================================================================== #
2728
+ # === Studium.return_question_answer_and_the_whole_exam_line_as_array
2729
+ # =========================================================================== #
2730
+ def self.return_question_answer_and_the_whole_exam_line_as_array(
2731
+ topic = 'random_topic',
2732
+ &block
2733
+ )
2734
+ _ = ::Studium::Exams::AskExamQuestion.new(topic, :do_not_run_yet, &block)
2735
+ if topic.is_a?(String) and topic.include?('-')
2736
+ _.set_exam_question_line_and_then_parse_that_line(topic)
2737
+ else
2738
+ _.invoke_all_the_necessary_steps_before_the_question_is_asked
2739
+ end
2740
+ _.disable_colours
2741
+ # ========================================================================= #
2742
+ # We will return the proper Array next:
2743
+ # ========================================================================= #
2744
+ [
2745
+ _.question?,
2746
+ _.answer?.to_s.delete("\n").squeeze(' '),
2747
+ _.line?
2748
+ ]
2749
+ end
2750
+
2751
+ end
2752
+
2753
+ if __FILE__ == $PROGRAM_NAME
2754
+ alias e puts
2755
+ _ask_exam_question = Studium::Exams::AskExamQuestion.new(ARGV)
2756
+ pp Studium.return_question_answer_as_array(:biotech2)
2757
+ end # qa amg1