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,2429 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === Studium::ExamsPerMonth
6
+ #
7
+ # This class will display how many exams I have passed per given month.
8
+ #
9
+ # Usage example:
10
+ #
11
+ # Studium::ExamsPerMonth.new
12
+ #
13
+ # =========================================================================== #
14
+ # require 'studium/exams_per_month/exams_per_month.rb'
15
+ # =========================================================================== #
16
+ require 'studium/base/base.rb'
17
+
18
+ module Studium
19
+
20
+ class ExamsPerMonth < Base # === Studium::ExamsPerMonth
21
+
22
+ require 'studium/toplevel_methods/regexes.rb'
23
+ require 'studium/ects/n_ects_points_in_mandatory_presence_courses.rb'
24
+ require 'studium/ects/ects_per_university/ects_per_university.rb'
25
+
26
+ # ======================================================================= #
27
+ # === TITLE
28
+ # ======================================================================= #
29
+ TITLE = 'Exams per Month'
30
+
31
+ # ======================================================================= #
32
+ # === LAST_YEAR
33
+ # ======================================================================= #
34
+ LAST_YEAR = Time.now.year
35
+
36
+ # ======================================================================= #
37
+ # === SHOW_N_BEST_MONTHS
38
+ #
39
+ # Determine how many "best months" to show, by default.
40
+ # ======================================================================= #
41
+ SHOW_N_BEST_MONTHS = 30
42
+
43
+ # ======================================================================= #
44
+ # === ARRAY_REGISTERED_MONTHS
45
+ #
46
+ # The months are stored in both the german and the english language.
47
+ # ======================================================================= #
48
+ ARRAY_REGISTERED_MONTHS = %w(
49
+ januar
50
+ februar
51
+ feb
52
+ märz
53
+ april
54
+ mai
55
+ juni
56
+ juli
57
+ august
58
+ september
59
+ oktober
60
+ november
61
+ dezember
62
+
63
+ january
64
+ february
65
+ march
66
+ april
67
+ may
68
+ june
69
+ july
70
+ october
71
+ december
72
+ )
73
+
74
+ # ========================================================================= #
75
+ # === initialize
76
+ # ========================================================================= #
77
+ def initialize(
78
+ commandline_arguments = nil,
79
+ run_already = true
80
+ )
81
+ reset
82
+ case commandline_arguments
83
+ when :dont_run_yet,
84
+ :do_not_run_yet
85
+ run_already = false
86
+ else
87
+ set_input(commandline_arguments)
88
+ end
89
+ # ======================================================================= #
90
+ # === Handle blocks next
91
+ # ======================================================================= #
92
+ if block_given?
93
+ yielded = yield
94
+ case yielded
95
+ # ===================================================================== #
96
+ # === --yearly-average-grades
97
+ # ===================================================================== #
98
+ when /^-?-?yearly(-|_)?average(-|_)?grades$/
99
+ sanitize_dataset
100
+ do_show_yearly_average_grades
101
+ report
102
+ end
103
+ end
104
+ try_to_require_the_open_gem
105
+ run if run_already
106
+ end
107
+
108
+ # ========================================================================= #
109
+ # === colour_for_hours
110
+ #
111
+ # Mediumorchid is the colour for hours.
112
+ # ========================================================================= #
113
+ def colour_for_hours(i)
114
+ return mediumorchid(i) if use_colours? # Delegate into mediumorchid() here in this file.
115
+ return i
116
+ end; alias colourize_hours colour_for_hours # === colourize_hours
117
+
118
+ # ========================================================================= #
119
+ # === colourize_year
120
+ # ========================================================================= #
121
+ def colourize_year(i)
122
+ return swarn(i) if use_colours?
123
+ return i
124
+ end
125
+
126
+ # ========================================================================= #
127
+ # === colourize_month_year
128
+ #
129
+ # This method will colourize strings such as '04.2017'.
130
+ #
131
+ # The current colour used here is 'goldenrod'.
132
+ # ========================================================================= #
133
+ def colourize_month_year(i)
134
+ return goldenrod(i) if use_colours?
135
+ return i
136
+ end
137
+
138
+ # ========================================================================= #
139
+ # === colourize_ects_points
140
+ #
141
+ # No need to check inside this method for konsole support because
142
+ # we already do so before that.
143
+ # ========================================================================= #
144
+ def colourize_ects_points(i)
145
+ return dodgerblue(i) if use_colours?
146
+ return i
147
+ end; alias colourize_ects colourize_ects_points # === colourize_ects
148
+ alias colour_ects colourize_ects_points # === colour_ects
149
+
150
+ # ========================================================================= #
151
+ # === colourize_n_exams
152
+ #
153
+ # Combound method to allow different colours.
154
+ # ========================================================================= #
155
+ def colourize_n_exams(
156
+ i,
157
+ use_this_colour = :lightslategray
158
+ )
159
+ if use_colours?
160
+ case use_this_colour # case tag
161
+ when :lightslategray # This is the default; we will use lightslategray.
162
+ i = lightslategray(i)
163
+ when :oldlace
164
+ i = oldlace(i)
165
+ when :mediumseagreen
166
+ i = mediumseagreen(i)
167
+ when :papayawhip
168
+ i = papayawhip(i)
169
+ end
170
+ end
171
+ return i
172
+ end
173
+
174
+ # ========================================================================= #
175
+ # === obtain_dataset
176
+ #
177
+ # The default value for the first argument is FILE_PASSED_EXAMS_PER_MONTH,
178
+ # which is represented by the method called main_file?.
179
+ # ========================================================================= #
180
+ def obtain_dataset(
181
+ use_this_file = main_file?
182
+ )
183
+ set_dataset(
184
+ raw_dataset?(use_this_file)
185
+ )
186
+ end
187
+
188
+ # ========================================================================= #
189
+ # === dataset?
190
+ # ========================================================================= #
191
+ def dataset?
192
+ @dataset
193
+ end
194
+
195
+ # ========================================================================= #
196
+ # === use_only_master_lectures
197
+ # ========================================================================= #
198
+ def use_only_master_lectures
199
+ set_dataset(
200
+ dataset?.select {|entry| entry[5].include? 'M' }
201
+ )
202
+ reset_main_hash
203
+ sanitize_dataset(dataset?)
204
+ end
205
+
206
+ # ========================================================================= #
207
+ # === set_dataset
208
+ # ========================================================================= #
209
+ def set_dataset(i)
210
+ @dataset = i
211
+ end
212
+
213
+ # ========================================================================= #
214
+ # === raw_dataset?
215
+ #
216
+ # This method will return an Array. The Array came from the file
217
+ # 'passed_exams_per_month.csv'.
218
+ # ========================================================================= #
219
+ def raw_dataset?(
220
+ use_this_file = main_file?
221
+ )
222
+ readlines_from_this_input_file(use_this_file).reject! {|entry|
223
+ entry.start_with? '#'
224
+ }.map(&:chomp).reject(&:empty?)
225
+ end
226
+
227
+ # ========================================================================= #
228
+ # === draw_image_with_gruff
229
+ #
230
+ # If we wish to draw an image with gruff then we use this method here.
231
+ # ========================================================================= #
232
+ def draw_image_with_gruff
233
+ begin
234
+ require 'gruff'
235
+ rescue LoadError; end
236
+ opne 'Startup of class '+sfancy(self.class.name)+'.'
237
+ @g = Gruff::Line.new(800)
238
+ @g.theme_keynote
239
+ @g.title_font_size = 25
240
+ @g.title = title?
241
+ @g.labels = {
242
+ 1 => '25.10.2005',
243
+ #10 => '13.11.2006',
244
+ 11 => '08.04.2014',
245
+ 20 => Time.now.strftime('%d.%m.%Y')
246
+ }
247
+ @g.data('Amount of exams per month',
248
+ [
249
+ 274,340,851,1114,1168,1195,1230,
250
+ 1245,1270,1315,1352,2524,2621],
251
+ 'slateblue')
252
+ @g.minimum_value = 1
253
+ # Finally, write down the results.
254
+ store_result
255
+ open_result_in_gimp
256
+ end
257
+
258
+ # ========================================================================= #
259
+ # === store_where?
260
+ # ========================================================================= #
261
+ def store_where?
262
+ @store_where
263
+ end
264
+
265
+ # ========================================================================= #
266
+ # === set_store_where
267
+ # ========================================================================= #
268
+ def set_store_where(i)
269
+ @store_where = i
270
+ end
271
+
272
+ # ========================================================================= #
273
+ # === store_result
274
+ # ========================================================================= #
275
+ def store_result
276
+ set_store_where '/SOURCE_FILES.png'
277
+ opne "We will store at `#{sfile(store_where?)}`."
278
+ @g.write(store_where?)
279
+ end
280
+
281
+ # ========================================================================= #
282
+ # === title?
283
+ # ========================================================================= #
284
+ def title?
285
+ TITLE
286
+ end
287
+
288
+ # ========================================================================= #
289
+ # === input?
290
+ # ========================================================================= #
291
+ def input?
292
+ @input
293
+ end
294
+
295
+ # ========================================================================= #
296
+ # === set_last_year
297
+ # ========================================================================= #
298
+ def set_last_year(i = current_year?)
299
+ @last_year = i
300
+ end
301
+
302
+ # ========================================================================= #
303
+ # === last_year?
304
+ # ========================================================================= #
305
+ def last_year?
306
+ @last_year
307
+ end; alias last_year last_year? # === last_year
308
+
309
+ # ========================================================================= #
310
+ # === current_year?
311
+ # ========================================================================= #
312
+ def current_year?
313
+ @current_year
314
+ end; alias current_year current_year? # === current_year
315
+
316
+ # ========================================================================= #
317
+ # === n_exams_passed?
318
+ # ========================================================================= #
319
+ def n_exams_passed?(for_this_year = @current_year)
320
+ @n_exams_passed
321
+ end
322
+
323
+ # ========================================================================= #
324
+ # === set_current_year
325
+ #
326
+ # This must be an Integer.
327
+ # ========================================================================= #
328
+ def set_current_year(
329
+ i = Time.now.strftime('%Y').to_i
330
+ )
331
+ i = i.to_i
332
+ @current_year = i
333
+ end
334
+
335
+ # ========================================================================= #
336
+ # === set_input
337
+ #
338
+ # The input can be an Array such as ["2013", "2015"], in which case we
339
+ # will only output certain numbers matching these criteria.
340
+ # ========================================================================= #
341
+ def set_input(i = nil)
342
+ if i.is_a? Array
343
+ unless i.empty? # We don't care about empty Arrays.
344
+ # ===================================================================== #
345
+ # === Determine whether our given input consists of only numbers.
346
+ # ===================================================================== #
347
+ only_numbers = i.all? {|number|
348
+ number.to_s =~ /^\d+$/ # Only numbers.
349
+ }
350
+ # ===================================================================== #
351
+ # If we compare only some numbers, we will check here.
352
+ # That is the whole point of the above check.
353
+ # ===================================================================== #
354
+ if only_numbers
355
+ @compare_these_numbers = i.map(&:to_i)
356
+ end
357
+ end
358
+ i = i.join(' ').strip
359
+ end
360
+ @input = i
361
+ end
362
+
363
+ # ========================================================================= #
364
+ # === do_show_only_grade_for
365
+ # ========================================================================= #
366
+ def do_show_only_grade_for(
367
+ i = nil
368
+ )
369
+ i = i.to_i if i
370
+ @show_only_grade_for = i
371
+ end
372
+
373
+ # ========================================================================= #
374
+ # === do_show_yearly_average_grades
375
+ # ========================================================================= #
376
+ def do_show_yearly_average_grades
377
+ @show_yearly_average_grades = true
378
+ end
379
+
380
+ # ========================================================================= #
381
+ # === show_ects_points?
382
+ # ========================================================================= #
383
+ def show_ects_points?
384
+ @show_ects_points
385
+ end
386
+
387
+ # ========================================================================= #
388
+ # === do_show_ects_points
389
+ # ========================================================================= #
390
+ def do_show_ects_points
391
+ @show_ects_points = true # If true then we will show the ECTS points as well.
392
+ end
393
+
394
+ # ========================================================================= #
395
+ # === output_the_csv_file
396
+ #
397
+ # We will either use Cat[], if it is available, or just File.read().
398
+ # ========================================================================= #
399
+ def output_the_csv_file
400
+ e File.read(csv_file?)
401
+ end
402
+
403
+ # ========================================================================= #
404
+ # === is_this_sommersemester_or_wintersemester?
405
+ #
406
+ # This method will return SS or WS, as String.
407
+ #
408
+ # The following months are Sommersemester (SS):
409
+ #
410
+ # März, April, Mai, Juni, Juli, August, September (3-9)
411
+ #
412
+ # The following months are Wintersemester (WS):
413
+ #
414
+ # Oktober, November, Dezember, Jänner, Februar (10-2)
415
+ # ========================================================================= #
416
+ def is_this_sommersemester_or_wintersemester?(i)
417
+ return_this_string = '' # Default zero.
418
+ case i.to_i # Need to have an Integer at this point.
419
+ when 3..9
420
+ return_this_string = 'SS'
421
+ when 10,11,12,1,2 # Has to be that way.
422
+ return_this_string = 'WS'
423
+ end
424
+ return return_this_string
425
+ end
426
+
427
+ # ========================================================================= #
428
+ # === output_colourized_year_and_colourized_hours
429
+ # ========================================================================= #
430
+ def output_colourized_year_and_colourized_hours(year)
431
+ unless @compare_these_numbers and !@compare_these_numbers.include?(year)
432
+ e colourize_year(year.to_s) # <- This will usually be red.
433
+ e " "\
434
+ "#{colourize_hours('n hours')}"
435
+ end
436
+ end
437
+
438
+ # ========================================================================= #
439
+ # === report_month_year_hours_ects_n_exams_passed_in_this_month
440
+ # ========================================================================= #
441
+ def report_month_year_hours_ects_n_exams_passed_in_this_month(
442
+ month, year, n_hours, n_ECTS, n_exams_passed_in_this_month
443
+ )
444
+ result = (
445
+ colourize_month_year(month.to_s.rjust(2,'0')+'.'+year.to_s)+
446
+ ':'+(' ' * 13)+ # <- Add n_hours next.
447
+ colourize_hours(n_hours.to_s.rjust(6))+' '
448
+ ).dup
449
+ # ======================================================================= #
450
+ # Conditionally add n_ECTS next.
451
+ # ======================================================================= #
452
+ if show_ects_points?
453
+ result << colourize_ects('('+n_ECTS.to_f.to_s.rjust(4)+' ECTS points)')
454
+ end
455
+ result << colourize_n_exams(' (n exams passed that month: '+
456
+ n_exams_passed_in_this_month.to_s.rjust(2)+')')
457
+ e result
458
+ end
459
+
460
+ # ========================================================================= #
461
+ # === show_help (help tag)
462
+ #
463
+ # To invoke this method, do:
464
+ #
465
+ # emo --help
466
+ #
467
+ # ========================================================================= #
468
+ def show_help
469
+ left_indent = (' ' * 26)+'# ' # For proper paragraph-indenting.
470
+ opne 'Currently these options are supported:'
471
+ e
472
+ e ' input numbers only to compare years, such as: '
473
+ e
474
+ e " #{sfancy('emo 2013 2015')}"
475
+ e
476
+ e ' --disable-colours # Do not use colours'
477
+ e ' --gruff # draw an image with gruff'
478
+ e ' --nl # show a numbered listing of the '\
479
+ 'passed exams, starting from 1 (== most recent exam)'
480
+ e ' --only-bachelor # show only Bachelor exams'
481
+ e ' --open # open the .csv file in the editor'
482
+ e ' --show # show / output the .csv file on '\
483
+ 'the terminal'
484
+ e ' --semesters # show the amount of ECTS points passed '\
485
+ 'per (full) semester'
486
+ e " --übungen # show only practical courses that were "\
487
+ "passed (#{sfancy('--practical')} is an alias to this)"
488
+ e ' --grades # show a distribution of my grades (1,2,3,4)'
489
+ e ' --grade={1,2,3,4,5] # show only grades that qualify for this'
490
+ e ' --yearly-average-grades # show the yearly average grades'
491
+ e ' --year=(dddd) # show only this specific year, such '\
492
+ 'as "year=2016"; year=1996-2013 is also'
493
+ e left_indent+'supported; you can also omit --"year" such as '\
494
+ 'in: emo --2005'
495
+ e ' --master # show only entries registered in '\
496
+ 'a master curriculum'
497
+ e ' --boku # show only exams at this given '\
498
+ 'university; also works with TU, UniWien etc'
499
+ e ' --summary # show only the summary over the '\
500
+ 'exam-dataset'
501
+ e ' --only-master-lectures # show only lectures that are part '\
502
+ 'of a (at the least one) master-curriculum.'
503
+ e ' --show-best-months # This will show the best 10-'+
504
+ SHOW_N_BEST_MONTHS.to_s+' months '\
505
+ 'or so, in regards to'
506
+ e left_indent+'n ECTS points accumulated'
507
+ e ' --years # show only the amount of ECTS '\
508
+ 'passed per year'
509
+ e ' --month # show the month, such as "emo --february"'
510
+ e ' "since 18.01.2013" # show only exams past this '\
511
+ 'specified date (in the mandatory format dd.mm.yyyy)'
512
+ e ' "before 18.01.2013" # show only exams before this '\
513
+ 'specified date (in the mandatory format dd.mm.yyyy)'
514
+ e
515
+ e 'The next options show how many exams were passed already '\
516
+ 'in a given curriculum:'
517
+ e
518
+ e ' emo --agrarwissenschaften'
519
+ e ' emo --lmbt'
520
+ e
521
+ end
522
+
523
+ # ========================================================================= #
524
+ # === menu (menu tag)
525
+ # ========================================================================= #
526
+ def menu(
527
+ i = input?
528
+ )
529
+ case i # case tag
530
+ # ======================================================================= #
531
+ # === emo --open
532
+ # ======================================================================= #
533
+ when /^-?-?OPEN$/i
534
+ open_the_main_files_in_the_editor
535
+ exit
536
+ # ======================================================================= #
537
+ # === emo --universities
538
+ #
539
+ # This entry point can be used to compare the different universities,
540
+ # in regards to solved ECTS.
541
+ # ======================================================================= #
542
+ when /^-?-?universities$/i,
543
+ /^-?-?unis$/i
544
+ show_ects_passed_per_university
545
+ exit
546
+ # ======================================================================= #
547
+ # === emo --boku
548
+ # ======================================================================= #
549
+ when /^-?-?boku$/,'BOKU'
550
+ show_only_exams_at_the_boku
551
+ # ======================================================================= #
552
+ # === emo "since 18.08.2013"
553
+ # ======================================================================= #
554
+ when /^-?-?since (\d{1,4}\.?\d{0,2}\.?\d{0,4})$/, # See: http://rubular.com/r/JMqr7aw3fs
555
+ /^-?-?after (\d{1,4}\.?\d{0,2}\.?\d{0,4})$/ # Or: emo "after 01.10.2018"
556
+ show_only_exams_past_this_date($1.to_s.dup)
557
+ # ======================================================================= #
558
+ # === emo --best-month-stats
559
+ # ======================================================================= #
560
+ when /^-?-?best(_|-)?month(_|-)?stats$/,
561
+ /^-?-?show(_|-)?best(_|-)?months?$/,
562
+ /^-?-?best(_|-)?months?$/
563
+ show_best_months
564
+ exit
565
+ # ======================================================================= #
566
+ # === emo --master
567
+ # ======================================================================= #
568
+ when /^-?-?master$/
569
+ @hash.clear
570
+ use_only_master_lectures
571
+ # ======================================================================= #
572
+ # === emo --years
573
+ # ======================================================================= #
574
+ when /^-?-?years$/,
575
+ /^-?-?table/,
576
+ /^-?-?short$/
577
+ show_the_years_in_a_short_table_overview
578
+ exit
579
+ # ======================================================================= #
580
+ # === emo --summary
581
+ # ======================================================================= #
582
+ when /^-?-?summary$/i
583
+ e; show_only_the_summary; e
584
+ exit
585
+ # ======================================================================= #
586
+ # === emo --half-split
587
+ # ======================================================================= #
588
+ when /--half-split/
589
+ show_half_split_exams_per_year
590
+ exit
591
+ # ======================================================================= #
592
+ # === emo --nl
593
+ # ======================================================================= #
594
+ when /nl/,
595
+ /^-?-?show(_|-)?numbered(_|-)?exams$/, # Simplified. emo --show-numbered-exams
596
+ /^-?-?show(_|-)?passed(_|-)?lectures$/i
597
+ show_numbered_exams
598
+ exit
599
+ # ======================================================================= #
600
+ # === emo --only-bachelor-lectures
601
+ # ======================================================================= #
602
+ when /^-?-?only(_|-)?bachelor$/,
603
+ /^-?-?only(_|-)?bachelor(_|-)?lectures$/,
604
+ /^-?-?only(_|-)?bachelorcurricula$/,
605
+ /^-?-?show(_|-)?only(_|-)?bachelor(_|-)?lectures$/,
606
+ /^-?-?show(_|-)?bachelor(_|-)?lectures$/
607
+ show_only_bachelor_lectures
608
+ exit
609
+ # ======================================================================= #
610
+ # === emo --only-master-lectures
611
+ # ======================================================================= #
612
+ when /^-?-?only(_|-)?master$/,
613
+ /^-?-?only(_|-)?master(_|-)?lectures$/,
614
+ /^-?-?only(_|-)?mastercurricula$/,
615
+ /^-?-?show(_|-)?only(_|-)?master(_|-)?lectures$/,
616
+ /^-?-?show(_|-)?master(_|-)?lectures$/
617
+ show_only_master_lectures
618
+ exit
619
+ # ======================================================================= #
620
+ # === emo --nocol
621
+ # ======================================================================= #
622
+ when /-?-?disable-?colours/,
623
+ /-?-?nocolours/,
624
+ /-?-?dcolours/,
625
+ /-?-?nocol/
626
+ disable_colours
627
+ show_n_exams_passed_per_month
628
+ # ======================================================================= #
629
+ # === emo --yearly-average-grades
630
+ # ======================================================================= #
631
+ when /^-?-?yearly(_|-)?average(_|-)?grades$/,
632
+ /^-?-?yearly(_|-)?grades$/
633
+ do_show_yearly_average_grades
634
+ # ======================================================================= #
635
+ # === emo --grades
636
+ # ======================================================================= #
637
+ when /-?-?grades/
638
+ do_show_the_grades_statistics
639
+ exit
640
+ # ======================================================================= #
641
+ # === emo --grade=4
642
+ # ======================================================================= #
643
+ when /--grade=(\d+)/
644
+ do_show_only_grade_for($1.to_s.dup)
645
+ show_n_exams_passed_per_month
646
+ # ======================================================================= #
647
+ # === emo --TU
648
+ # ======================================================================= #
649
+ when /-?-?TU$/,
650
+ /-?-?tu$/,
651
+ /-?-?tuwien/
652
+ show_only_exams_at_the_tu
653
+ # ======================================================================= #
654
+ # === emo "before 18.08.2013"
655
+ # ======================================================================= #
656
+ when /-?-?before (\d{1,4}\.?\d{0,2}\.?\d{0,4})/, # Sync this with the regex including "since".
657
+ /-?-?until (\d{1,4}\.?\d{0,2}\.?\d{0,4})/
658
+ show_only_exams_before_this_date($1.to_s.dup)
659
+ # ======================================================================= #
660
+ # === emo --year=2016
661
+ # ======================================================================= #
662
+ when /-?-?year=(\d+-?\d*)/,
663
+ /-?-?(\d{4})/,
664
+ /-?-?(\d{4}-?\d*)/ # See: http://rubular.com/r/JzUhbWSzKx
665
+ do_show_only_this_year_here($1.to_s.dup)
666
+ # ======================================================================= #
667
+ # === emo --uniwien
668
+ # ======================================================================= #
669
+ when /-?-?uniwien/,'--uniw',/-?-?wien/,'UNIWIEN','WIEN',
670
+ /-?-?vienna/
671
+ show_only_exams_at_the_uniwien
672
+ # ======================================================================= #
673
+ # === emo --meduni
674
+ # ======================================================================= #
675
+ when /-?-?meduni$/,'--medu','--med','MEDUNI','MED','meduniwien',
676
+ 'meduni'
677
+ show_only_exams_at_the_meduni
678
+ # ======================================================================= #
679
+ # === emo --vetmed
680
+ # ======================================================================= #
681
+ when /-?-?vetmed/,'--vet','VET','VETMED'
682
+ show_only_exams_at_the_vetmed_uni
683
+ # ======================================================================= #
684
+ # === emo --only-bachelor
685
+ # ======================================================================= #
686
+ when /-?-?only-?bachelor/ # Simplified. Should work for now.
687
+ show_only_bachelor_exams
688
+ # ======================================================================= #
689
+ # === emo --individuell_bachelor
690
+ # ======================================================================= #
691
+ when /-?-?(individuell(_|-| )?bachelor)/
692
+ show_how_many_exams_we_have_passed_in_this_curriculum($1.to_s.dup)
693
+ exit
694
+ # ======================================================================= #
695
+ # === emo --übungen
696
+ # ======================================================================= #
697
+ when /-?-?übungen/,
698
+ /--practical/
699
+ show_only_practical_courses_that_were_passed_already
700
+ # ======================================================================= #
701
+ # === emo --semesters
702
+ # ======================================================================= #
703
+ when /-?-?semesters\??/
704
+ show_exam_ects_points_passed_per_semester
705
+ exit
706
+ # ======================================================================= #
707
+ # === emo --reversed-nl
708
+ # ======================================================================= #
709
+ when /-?-?reversed?-?nl/
710
+ show_numbered_exams(:reversed)
711
+ exit
712
+ # ======================================================================= #
713
+ # === emo --master-lmbt
714
+ # ======================================================================= #
715
+ when /-?-?(master-?lmbt)/
716
+ show_how_many_exams_we_have_passed_in_this_curriculum($1.to_s.dup)
717
+ exit
718
+ # ======================================================================= #
719
+ # === emo --lmbt
720
+ # ======================================================================= #
721
+ when /-?-?(lmbt)/,/-?-?(lbt)/
722
+ show_how_many_exams_we_have_passed_in_this_curriculum($1.to_s.dup)
723
+ exit
724
+ # ======================================================================= #
725
+ # === emo --agrarwissenschaften
726
+ # ======================================================================= #
727
+ when /-?-?(agrarwissenschaften)/,/-?-?(AW)/
728
+ show_how_many_exams_we_have_passed_in_this_curriculum($1.to_s.dup)
729
+ exit
730
+ # ======================================================================= #
731
+ # === emo --show
732
+ # ======================================================================= #
733
+ when '--show','--output'
734
+ output_the_csv_file
735
+ exit
736
+ # ======================================================================= #
737
+ # === emo --help
738
+ # ======================================================================= #
739
+ when 'HELP',/^-?-?help$/
740
+ show_help
741
+ exit
742
+ # ======================================================================= #
743
+ # === emo --gruff
744
+ # ======================================================================= #
745
+ when 'gruff','--gruff','image'
746
+ draw_image_with_gruff # We could also create an image with gruff.
747
+ else # Else use the default here. (else tag)
748
+ # ===================================================================== #
749
+ # === emo /Agrarökolog/
750
+ # ===================================================================== #
751
+ if i and i.is_a?(String) and i.start_with?('/') and
752
+ (i.count('/') > 1) # <-- To check for pseudo-regexes here.
753
+ use_this_regexp = Regexp.new(i.delete('/'), Regexp::IGNORECASE)
754
+ Studium.try_to_report_exams_that_match_to_this_regexp(use_this_regexp)
755
+ exit
756
+ # ===================================================================== #
757
+ # === emo --januar
758
+ # ===================================================================== #
759
+ elsif i and ARRAY_REGISTERED_MONTHS.include?(i.delete('-').downcase)
760
+ show_all_exams_from_this_month(i.downcase)
761
+ exit
762
+ else # In the past, we used to report here, but since as of May 2017,
763
+ # we will actually default to the "report" method being called
764
+ # from within run().
765
+ # show_n_exams_passed_per_month
766
+ end
767
+ end
768
+ end; alias check_against_menu menu # === check_against_menu
769
+
770
+ # ========================================================================= #
771
+ # === file_lecture_information?
772
+ #
773
+ # On Roebe, we will use the file in the home system.
774
+ # ========================================================================= #
775
+ def file_lecture_information?(
776
+ _ = Studium.file_lecture_information
777
+ )
778
+ if is_on_roebe?
779
+ # ===================================================================== #
780
+ # On roebe we have to modify this a little bit:
781
+ # ===================================================================== #
782
+ _ = "#{RUBY_STUDIUM_HOME_DIR}yaml/"\
783
+ "lecture_information/#{File.basename(_)}"
784
+ end
785
+ return _
786
+ end
787
+
788
+ # ========================================================================= #
789
+ # === main_file?
790
+ # ========================================================================= #
791
+ def main_file?
792
+ self.class.main_file?
793
+ end
794
+
795
+ # ========================================================================= #
796
+ # === menu_file?
797
+ # ========================================================================= #
798
+ def menu_file?
799
+ self.class.menu_file?
800
+ end
801
+
802
+ # ========================================================================= #
803
+ # === open_the_curricula_assigned_exams_file_in_the_editor
804
+ # ========================================================================= #
805
+ def open_the_curricula_assigned_exams_file_in_the_editor
806
+ _ = Studium::ExamsPerMonth.curricula_assigned_exams_file?
807
+ Open.in_editor(_) if File.exist? _
808
+ end
809
+
810
+ # ========================================================================= #
811
+ # === open_the_main_file_in_the_editor
812
+ # ========================================================================= #
813
+ def open_the_main_file_in_the_editor
814
+ Open.in_editor(main_file?)
815
+ end
816
+
817
+ # ========================================================================= #
818
+ # === open_the_menu_file_in_the_editor
819
+ # ========================================================================= #
820
+ def open_the_menu_file_in_the_editor
821
+ Open.in_editor(menu_file?)
822
+ end
823
+
824
+ # ========================================================================= #
825
+ # === open_the_file_lecture_information_in_the_editor
826
+ # ========================================================================= #
827
+ def open_the_file_lecture_information_in_the_editor(
828
+ i = file_lecture_information?
829
+ )
830
+ Open.in_editor(i)
831
+ end
832
+
833
+ # ========================================================================= #
834
+ # === Studium::ExamsPerMonth.open_main_files_in_the_editor
835
+ #
836
+ # In the past file_theme_of_exams? was part of the Array defined
837
+ # below, but as of 26.03.2019 I decided that this file is no
838
+ # longer useful to me - it will eventually be phased out.
839
+ #
840
+ # Invocation example to use this method from the commandline:
841
+ #
842
+ # studium --open
843
+ #
844
+ # ========================================================================= #
845
+ def self.open_main_files_in_the_editor
846
+ array_open_these_files = [
847
+ main_file?,
848
+ curricula_assigned_exams_file?
849
+ ]
850
+ unless Object.const_defined? :Open
851
+ begin
852
+ require 'open'
853
+ rescue LoadError; end
854
+ end
855
+ array_open_these_files.each {|file|
856
+ Open.in_editor(file)
857
+ }
858
+ end
859
+
860
+ # ========================================================================= #
861
+ # === open_result_in_gimp
862
+ #
863
+ # This method is, quite obviously, for image-files.
864
+ # ========================================================================= #
865
+ def open_result_in_gimp
866
+ esystem "gimp #{store_where?} &"
867
+ end
868
+
869
+ # ========================================================================= #
870
+ # === reset (reset tag)
871
+ # ========================================================================= #
872
+ def reset
873
+ super() # Initialize the instance variables of the parent-class reset() method.
874
+ do_show_ects_points
875
+ infer_the_namespace
876
+ # ======================================================================= #
877
+ # === @shall_we_report
878
+ # ======================================================================= #
879
+ @shall_we_report = true # Whether to output anything or not.
880
+ # ======================================================================= #
881
+ # === @show_only_grade_for
882
+ # ======================================================================= #
883
+ @show_only_grade_for = nil # Set the initial state.
884
+ # ======================================================================= #
885
+ # === @total_grade
886
+ # ======================================================================= #
887
+ @total_grade = 0
888
+ # ======================================================================= #
889
+ # === @n_exams_in_total_passed
890
+ # ======================================================================= #
891
+ @n_exams_in_total_passed = 0
892
+ # ======================================================================= #
893
+ # === @n_ects_points_belonging_to_mandatory_presence_courses
894
+ #
895
+ # The next variable keeps track over how many ECTS points belong to
896
+ # a "prüfungsimmanente" lecture, aka one requiring mandatory presence.
897
+ # ======================================================================= #
898
+ @n_ects_points_belonging_to_mandatory_presence_courses = 0
899
+ # ======================================================================= #
900
+ # === @total_ects_points
901
+ # ======================================================================= #
902
+ @total_ects_points = 0 # The total amount of ECTS points per given month.
903
+ # ======================================================================= #
904
+ # === @n_ects_points
905
+ # ======================================================================= #
906
+ @n_ects_points = 0 # How many ECTS points this exam has.
907
+ # ======================================================================= #
908
+ # === @n_ects_points_in_total
909
+ # ======================================================================= #
910
+ @n_ects_points_in_total = 0 # The total amount of ECTS points altogether.
911
+ # ======================================================================= #
912
+ # === @n_hours_passed_in_total
913
+ # ======================================================================= #
914
+ @n_hours_passed_in_total = 0 # How many hours of exams did we pass.
915
+ # ======================================================================= #
916
+ # === @compare_these_numbers
917
+ # ======================================================================= #
918
+ @compare_these_numbers = nil
919
+ # ======================================================================= #
920
+ # === @show_only_this_year
921
+ # ======================================================================= #
922
+ @show_only_this_year = nil
923
+ enable_colours
924
+ # ======================================================================= #
925
+ # === @show_average_ects_passed_per_exam
926
+ # ======================================================================= #
927
+ @show_average_ects_passed_per_exam = true
928
+ # ======================================================================= #
929
+ # === @show_yearly_average_grades
930
+ # ======================================================================= #
931
+ @show_yearly_average_grades = false
932
+ # ======================================================================= #
933
+ # === @show_n_best_months
934
+ # ======================================================================= #
935
+ @show_n_best_months = SHOW_N_BEST_MONTHS
936
+ # ======================================================================= #
937
+ # === @dataset_from_the_file_lecture_information
938
+ # ======================================================================= #
939
+ @dataset_from_the_file_lecture_information =
940
+ return_dataset_from_the_file_lecture_information
941
+ set_current_year(Time.now.strftime('%Y').to_i)
942
+ set_last_year
943
+ reset_main_hash
944
+ obtain_dataset # This will set the @dataset variable.
945
+ end
946
+
947
+ # ========================================================================= #
948
+ # === reset_main_hash
949
+ # ========================================================================= #
950
+ def reset_main_hash
951
+ @hash = {}
952
+ @hash.default = []
953
+ end
954
+
955
+ # ========================================================================= #
956
+ # === reset_n_hours
957
+ # ========================================================================= #
958
+ def reset_n_hours
959
+ @n_hours_passed_in_total = 0
960
+ end; alias reset_hours reset_n_hours # === reset_hours
961
+
962
+ # ========================================================================= #
963
+ # === reset_ects_points
964
+ # ========================================================================= #
965
+ def reset_ects_points
966
+ @n_ects_points = 0
967
+ end; alias reset_ects reset_ects_points # === reset_ects
968
+
969
+ # ========================================================================= #
970
+ # === sanitize_dataset
971
+ #
972
+ # Purpose of this method is to give us a sorted hash with the specific
973
+ # entries. In order for this to work, simply pass in your dataset into
974
+ # this method. By default, we will use the dataset? object, which
975
+ # is essentially just the @dataset instance variable.
976
+ #
977
+ # The initial dataset should have 6 entries, thus 5 occurrences of '|'.
978
+ #
979
+ # Example for such a dataset/line:
980
+ #
981
+ # "06.07.2018 | 1.0 | 1.0 | 1 | UniWien | M | VO | 270073 | 2018S | Nukleinsäureanalytik-Genomics"
982
+ #
983
+ # ========================================================================= #
984
+ def sanitize_dataset(
985
+ i = dataset?,
986
+ modify_time_entry = true
987
+ )
988
+ @n_ects_points_belonging_to_mandatory_presence_courses = 0 # Reset it here.
989
+ case modify_time_entry
990
+ # ======================================================================= #
991
+ # === :leave_time_entry_alone
992
+ # ======================================================================= #
993
+ when :leave_time_entry_alone
994
+ modify_time_entry = false
995
+ end
996
+ # ======================================================================= #
997
+ # Re-assign the @dataset here.
998
+ # ======================================================================= #
999
+ @dataset = i.map {|entry|
1000
+ if entry.is_a? Array
1001
+ splitted = entry
1002
+ else
1003
+ # =================================================================== #
1004
+ # Ensure that the encoding is proper here.
1005
+ # =================================================================== #
1006
+ encoding_to_use = ::Studium.encoding?
1007
+ unless entry.encoding.to_s.include? encoding_to_use
1008
+ entry = entry.force_encoding(encoding_to_use)
1009
+ end
1010
+ splitted = entry.split(' | ') # .reverse
1011
+ end
1012
+ if splitted.size <= 2 # Assume this to be an invalid entry.
1013
+ splitted = nil
1014
+ else
1015
+ # =================================================================== #
1016
+ # Modify the time-entry which is the first entry.
1017
+ # We don't need the day, only the specific month. But this is not
1018
+ # always wanted, so we also must honour an option passed into this
1019
+ # method.
1020
+ # =================================================================== #
1021
+ if modify_time_entry
1022
+ formatted_time = splitted[0].split('.')[1..-1].join('.') # This entry is now something such as "10.2001"
1023
+ splitted[0] = formatted_time
1024
+ end
1025
+ # =================================================================== #
1026
+ # === Compare only specific years
1027
+ #
1028
+ # If the user wants to compare only specific years, we enter
1029
+ # the next section.
1030
+ # =================================================================== #
1031
+ if @compare_these_numbers and formatted_time
1032
+ the_year = formatted_time.split('.').last.to_i
1033
+ unless @compare_these_numbers.include? the_year
1034
+ splitted = nil
1035
+ end
1036
+ end
1037
+ end
1038
+ splitted
1039
+ }
1040
+ @dataset.compact! # Weed out nil-values.
1041
+ @n_exams_passed = 0
1042
+ # ======================================================================= #
1043
+ # Next we populate our hash, which is used to report stuff.
1044
+ #
1045
+ # We will store the amount of hours passed, the amount of ECTS points
1046
+ # that were achieved, and count up for the amount of exams that were
1047
+ # passed.
1048
+ # ======================================================================= #
1049
+ @dataset.each {|entry|
1050
+ entry.map!(&:strip)
1051
+ month_and_year = entry[0] # Month and Year is the first entry.
1052
+ n_hours = entry[1].to_f # n hours is the second entry.
1053
+ n_ects_points = entry[2].to_f # n ects points is the third entry.
1054
+ # ===================================================================== #
1055
+ # The grade is a bit problematic. It has to be kept as an Array.
1056
+ # ===================================================================== #
1057
+ grade = entry[3] # The grade, the fourth entry. Can be 1,2,3,4,5 or '+'.
1058
+ university = entry[4].strip.downcase # The university at fifth position.
1059
+ _curriculum_type = entry[5].strip # The curriculum type such as Bachelor or Master. Currently not used here.
1060
+ lecture_type = entry[6].strip # The lecture type such as VO, UE, VU, SE.
1061
+ if is_a_prüfungsimmanent_course?(lecture_type)
1062
+ @n_ects_points_belonging_to_mandatory_presence_courses += n_ects_points
1063
+ end
1064
+ @n_exams_passed += 1
1065
+ # ===================================================================== #
1066
+ # === Put the dataset into the @hash instance variable next
1067
+ # ===================================================================== #
1068
+ if @hash.has_key? month_and_year
1069
+ # =================================================================== #
1070
+ # In this case, add it because we already did initialize it.
1071
+ # =================================================================== #
1072
+ new_n_hours = @hash[month_and_year][0]+n_hours
1073
+ new_n_ects_points = @hash[month_and_year][1]+n_ects_points
1074
+ array_grade = @hash[month_and_year][2] << grade
1075
+ @hash[month_and_year] = [
1076
+ new_n_hours, new_n_ects_points, array_grade, university, @n_exams_passed
1077
+ ]
1078
+ else # Else simply append it, as it is a new month.
1079
+ @n_exams_passed = 0 # And reset it here again.
1080
+ @n_exams_passed += 1 # Must be at least one.
1081
+ @hash[month_and_year] = [
1082
+ n_hours, n_ects_points, [grade], university, @n_exams_passed
1083
+ ]
1084
+ end
1085
+ }
1086
+ end
1087
+
1088
+ # ========================================================================= #
1089
+ # === calculate_the_average_amount_per_passed_exam
1090
+ # ========================================================================= #
1091
+ def calculate_the_average_amount_per_passed_exam
1092
+ ects_per_exams_passed = # This is: total ects / n_exams
1093
+ (
1094
+ @n_ects_points_in_total.to_f / @n_exams_in_total_passed.to_f
1095
+ ).round(2)
1096
+ return ects_per_exams_passed
1097
+ end
1098
+
1099
+ # ========================================================================= #
1100
+ # === show_half_split_exams_per_year
1101
+ #
1102
+ # This method can be used to show how many exams were passed, per
1103
+ # year, in each half of that year.
1104
+ #
1105
+ # Invocation example:
1106
+ #
1107
+ # emo --half-split
1108
+ #
1109
+ # ========================================================================= #
1110
+ def show_half_split_exams_per_year
1111
+ array_early_months = %w( 1 2 3 4 5 6 ).map(&:to_i)
1112
+ array_late_months = %w( 7 8 9 10 11 12 ).map(&:to_i)
1113
+ hash = {}
1114
+ raw_dataset?.each {|this_line|
1115
+ next unless this_line.include? '|'
1116
+ splitted = this_line.strip.split('|').map(&:strip)
1117
+ first_element = splitted.first # e. g. '25.11.1997'
1118
+ n_ects = splitted[2].to_f
1119
+ year = first_element.split('.').last
1120
+ hash[year] = {
1121
+ :early_months => 0,
1122
+ :late_months => 0
1123
+ } unless hash.has_key? year
1124
+ month = first_element.split('.')[1].to_i
1125
+ if array_early_months.include? month
1126
+ hash[year][:early_months] += n_ects
1127
+ elsif array_late_months.include? month
1128
+ hash[year][:late_months] += n_ects
1129
+ end
1130
+ }
1131
+ # ======================================================================= #
1132
+ # Next, we will display that Hash, but only if we have any ECTS
1133
+ # points to report..
1134
+ # ======================================================================= #
1135
+ hash.each_pair {|year, value|
1136
+ n_ljust = 28
1137
+ first_half_ects_points = value[:early_months].to_f
1138
+ second_half_ects_points = value[:late_months].to_f
1139
+ unless ( (first_half_ects_points == 0) and (second_half_ects_points == 0) )
1140
+ e slateblue(year+':')
1141
+ e
1142
+ if first_half_ects_points > 0
1143
+ e (' Start of the year '+year+': ').ljust(n_ljust)+
1144
+ orange(first_half_ects_points.to_s.rjust(4)+' ECTS points')
1145
+ end
1146
+ if second_half_ects_points > 0
1147
+ e (' End of the year '+year+':').ljust(n_ljust)+
1148
+ orange(second_half_ects_points.to_s.rjust(4)+' ECTS points')
1149
+ end
1150
+ e
1151
+ end
1152
+ }
1153
+ end
1154
+
1155
+ # ========================================================================= #
1156
+ # === do_show_only_this_year_here
1157
+ #
1158
+ # Use this method if you only want to show a specific year, such as
1159
+ # 2013 or 2017 and so forth.
1160
+ # ========================================================================= #
1161
+ def do_show_only_this_year_here(i)
1162
+ @show_only_this_year = i # This variable may also contain a '-' character.
1163
+ # ======================================================================= #
1164
+ # Next, select only these entries from the dataset that have
1165
+ # a matching year entry.
1166
+ # ======================================================================= #
1167
+ _ = dataset?.select {|entry| # === emo --year=1997-2009
1168
+ the_year = entry.first.strip.split('.').last.to_s
1169
+ is_it_included = false
1170
+ is_it_included = true if @show_only_this_year == the_year
1171
+ # =================================================================== #
1172
+ # === Range input
1173
+ #
1174
+ # First, handle '-' input given.
1175
+ # =================================================================== #
1176
+ if @show_only_this_year.include? '-'
1177
+ # ================================================================= #
1178
+ # Then we turn it into a range, in order to look whether the
1179
+ # year is within that given Range.
1180
+ # ================================================================= #
1181
+ range = Range.new(*@show_only_this_year.split('-').map(&:to_i))
1182
+ if range.include? the_year.to_i # Since we work with numbers past this point.
1183
+ is_it_included = true
1184
+ end
1185
+ end
1186
+ is_it_included
1187
+ }
1188
+ reset_main_hash # Empty @hash again.
1189
+ sanitize_dataset(_, :leave_time_entry_alone)
1190
+ end
1191
+
1192
+ # ========================================================================= #
1193
+ # === show_only_exams_at_the_vetmed_uni
1194
+ #
1195
+ # Invoke this method like so:
1196
+ # emo --vetmed
1197
+ # ========================================================================= #
1198
+ def show_only_exams_at_the_vetmed_uni
1199
+ opne 'Showing all exams passed at the Vetmed Uni.'
1200
+ _ = dataset?.select {|entry|
1201
+ name_of_university = entry[4]
1202
+ (name_of_university.strip.downcase == 'vetmed')
1203
+ }
1204
+ reset_main_hash
1205
+ sanitize_dataset(_, :leave_time_entry_alone)
1206
+ end
1207
+
1208
+ # ========================================================================= #
1209
+ # === show_numbered_exams
1210
+ #
1211
+ # This method will output the passed exams.
1212
+ #
1213
+ # To output this method, try this:
1214
+ # emo --show-numbered-exams
1215
+ # emo --reversed-nl
1216
+ # ========================================================================= #
1217
+ def show_numbered_exams(normal_or_reversed = :normal)
1218
+ dataset = File.readlines(csv_file?).reject {|entry|
1219
+ entry.start_with? '#'
1220
+ }.reject {|entry|
1221
+ entry.to_s.strip.empty?
1222
+ }
1223
+ size_of_the_dataset = dataset.size
1224
+ e; dataset.each_with_index {|line, index|
1225
+ index += 1
1226
+ if normal_or_reversed == :reversed
1227
+ index = (size_of_the_dataset - index)+1
1228
+ end
1229
+ e ' '+orange(index.to_s.rjust(4))+') '+simp(line.chomp)
1230
+ }; e
1231
+ end
1232
+
1233
+ # ========================================================================= #
1234
+ # === show_only_exams_at_the_uniwien
1235
+ #
1236
+ # Invoke this method like so:
1237
+ #
1238
+ # emo --uniwien
1239
+ #
1240
+ # ========================================================================= #
1241
+ def show_only_exams_at_the_uniwien
1242
+ opne 'Showing all exams passed at the UniWien.'
1243
+ _ = dataset?.select {|entry|
1244
+ name_of_university = entry[4]
1245
+ (name_of_university.strip.downcase == 'uniwien')
1246
+ }
1247
+ reset_main_hash
1248
+ sanitize_dataset(_, :leave_time_entry_alone)
1249
+ end
1250
+
1251
+ # ========================================================================= #
1252
+ # === show_only_exams_at_the_meduni
1253
+ #
1254
+ # Invoke this method like so:
1255
+ # emo --meduni
1256
+ # ========================================================================= #
1257
+ def show_only_exams_at_the_meduni
1258
+ opne 'Showing all exams passed at the MedUni Wien.'
1259
+ _ = dataset?.select {|entry|
1260
+ name_of_university = entry[4]
1261
+ (name_of_university.strip.downcase == 'meduni')
1262
+ }
1263
+ reset_main_hash
1264
+ sanitize_dataset(_, :leave_time_entry_alone)
1265
+ end
1266
+
1267
+ # ========================================================================= #
1268
+ # === show_all_exams_from_this_month
1269
+ #
1270
+ # Use this method to show all exams from a given month only.
1271
+ #
1272
+ # We also support english names for the months, since as of April 2017.
1273
+ #
1274
+ # Usage example:
1275
+ # emo --januar
1276
+ # ========================================================================= #
1277
+ def show_all_exams_from_this_month(i = 'januar')
1278
+ i.delete!('-') if i.include? '-'
1279
+ i.downcase!
1280
+ # ======================================================================= #
1281
+ # Next, sanitize the month.
1282
+ # ======================================================================= #
1283
+ case i # case tag
1284
+ when 'januar','january'
1285
+ i = '01'
1286
+ when 'februar','february',/feb/
1287
+ i = '02'
1288
+ when 'märz','march'
1289
+ i = '03'
1290
+ when 'april'
1291
+ i = '04'
1292
+ when 'mai','may'
1293
+ i = '05'
1294
+ when 'juni','june'
1295
+ i = '06'
1296
+ when 'juli','july'
1297
+ i = '07'
1298
+ when 'august'
1299
+ i = '08'
1300
+ when 'september'
1301
+ i = '09'
1302
+ when 'oktober','october'
1303
+ i = '10'
1304
+ when 'november'
1305
+ i = '11'
1306
+ when 'dezember','december'
1307
+ i = '12'
1308
+ end
1309
+ _ = dataset?.select {|inner_array|
1310
+ month_and_year = inner_array.first
1311
+ splitted = month_and_year.split('.')
1312
+ month = splitted.first
1313
+ month == i
1314
+ }
1315
+ reset_main_hash
1316
+ sanitize_dataset(_, :leave_time_entry_alone)
1317
+ end
1318
+
1319
+ # ========================================================================= #
1320
+ # === show_only_practical_courses_that_were_passed_already
1321
+ #
1322
+ # Use this method if you wish to show only practical courses that
1323
+ # were passed already.
1324
+ #
1325
+ # The currently acknowledged practical courses include UE, PR and LU.
1326
+ #
1327
+ # Invocation example:
1328
+ # emo --übungen
1329
+ # ========================================================================= #
1330
+ def show_only_practical_courses_that_were_passed_already
1331
+ @show_average_ects_passed_per_exam = false # This method won't report average amount of ECTS per exam.
1332
+ _ = dataset?
1333
+ _.select! {|entry|
1334
+ type_of_lecture = entry[6].strip
1335
+ type_of_lecture.include?('UE') or
1336
+ type_of_lecture.include?('PR') or
1337
+ type_of_lecture.include?('LU')
1338
+ }
1339
+ reset_main_hash
1340
+ sanitize_dataset(_, :leave_time_entry_alone)
1341
+ report_main_hash
1342
+ end
1343
+
1344
+ # ========================================================================= #
1345
+ # === show_exam_ects_points_passed_per_semester
1346
+ # ========================================================================= #
1347
+ def show_exam_ects_points_passed_per_semester
1348
+ # ======================================================================= #
1349
+ # First, we need a way to group months into "sommersemester" or
1350
+ # "wintersemester.
1351
+ # ======================================================================= #
1352
+ hash = {}
1353
+ _ = dataset?
1354
+ opne 'We will next show how many exams were passed in a given semester.'
1355
+ # ======================================================================= #
1356
+ # Each entry in the dataset looks like this:
1357
+ # ["10.2001", "3.0"," xxx","4", "UniWien", " D ", " 898249 ","Allgemeine Biologie III"],
1358
+ # SWS ECTS
1359
+ # And it is already sorted.
1360
+ # ======================================================================= #
1361
+ _.each {|inner_array|
1362
+ _n_wochenstunden = inner_array[1]
1363
+ n_ects_points = inner_array[2]
1364
+ _name_of_the_lecture = inner_array.last
1365
+ month_year = inner_array.first
1366
+ year = month_year.dup
1367
+ if month_year.include? '.'
1368
+ splitted = month_year.split('.')
1369
+ month_year = splitted.first
1370
+ year = splitted.last.to_i
1371
+ end
1372
+ sommersemester_or_wintersemester = is_this_sommersemester_or_wintersemester?(
1373
+ month_year
1374
+ )
1375
+ # ======================================================================= #
1376
+ # Note that the Wintersemester may be from the last year, so we
1377
+ # may have to deduct 1. This will be the case only for January
1378
+ # and February though.
1379
+ # ======================================================================= #
1380
+ month_as_number = month_year.split('.').first.to_i
1381
+ if (sommersemester_or_wintersemester == 'WS') and
1382
+ [1,2].include?(month_as_number)
1383
+ year -= 1
1384
+ end
1385
+ # ======================================================================= #
1386
+ # Every time a toggle from SS to WS happens, we populate it into
1387
+ # another Hash. Note that we only care for when the exam was
1388
+ # officially registered and simply count this as a "sommersemester"
1389
+ # or "wintersemester" lecture.
1390
+ # ======================================================================= #
1391
+ hash_key_to_use = sommersemester_or_wintersemester+' '+year.to_s
1392
+ if hash.has_key? hash_key_to_use # Then add to it.
1393
+ hash[hash_key_to_use] = hash[hash_key_to_use]+n_ects_points.to_f
1394
+ else
1395
+ hash[hash_key_to_use] = n_ects_points.to_f
1396
+ end
1397
+ }
1398
+ e 'We have determined these ECTS points per semester:'; e
1399
+ hash.each_pair {|semester_and_year, n_ects_points|
1400
+ e ' '+simp(semester_and_year.ljust(8))+' '+
1401
+ sfancy(((n_ects_points.to_s.rjust(4))+' ECTS').rjust(8))
1402
+ }
1403
+ e; e 'Total ECTS points: '+simp(hash.values.sum.to_s)
1404
+ end
1405
+
1406
+ # ========================================================================= #
1407
+ # === show_only_exams_before_this_date
1408
+ #
1409
+ # The argument to this method should be the starting time, the day at
1410
+ # which you wish to keep track of exams made BEFORE this date.
1411
+ #
1412
+ # To invoke this method, do:
1413
+ # emo "before 10.01.2011"
1414
+ # ========================================================================= #
1415
+ def show_only_exams_before_this_date(this_date)
1416
+ unless this_date.include? '.'
1417
+ this_date.prepend('01.01.') # In this case, we assume this to mean the first January.
1418
+ end
1419
+ opne 'Showing only passed exams before the date '+simp(this_date.to_s)+'.'
1420
+ # ======================================================================= #
1421
+ # Convert a String into a time object.
1422
+ # ======================================================================= #
1423
+ this_date = Time.parse(this_date) if this_date.is_a? String
1424
+ a = this_date # Shorter to type. :)
1425
+ _ = dataset?
1426
+ new_array_with_matches = []
1427
+ _.each {|entry|
1428
+ date = Time.parse('01.'+entry.first.strip) # Must insert date here.
1429
+ b = date
1430
+ if a > b
1431
+ new_array_with_matches << entry
1432
+ end
1433
+ }
1434
+ reset_main_hash
1435
+ sanitize_dataset(new_array_with_matches, :leave_time_entry_alone)
1436
+ end
1437
+
1438
+ # ========================================================================= #
1439
+ # === show_only_bachelor_exams
1440
+ #
1441
+ # Use this method to show only exams relevant for the Bachelor.
1442
+ #
1443
+ # Invocation example:
1444
+ # emo --show-only-bachelor
1445
+ # ========================================================================= #
1446
+ def show_only_bachelor_exams
1447
+ opne 'Showing only Bachelor exams.'
1448
+ _ = dataset?.select {|entry|
1449
+ curriculum_type = entry[5].strip # The sixth entry is the bachelor/master distinction.
1450
+ curriculum_type.include? 'B'
1451
+ }
1452
+ reset_main_hash
1453
+ sanitize_dataset(_, :leave_time_entry_alone)
1454
+ end
1455
+
1456
+ # ========================================================================= #
1457
+ # === show_only_master_lectures
1458
+ #
1459
+ # This method is tasked to show only master lectures. For this purpose,
1460
+ # we define a lecture to be a "master" lecture if it is part of at the
1461
+ # least one master-curriculum. With this definition, a lecture that
1462
+ # is registered in both a bachelor and a master curriculum, will
1463
+ # satisfy this defintion and thus be listed.
1464
+ #
1465
+ # We will take the file passed_exams_per_month.csv for this.
1466
+ #
1467
+ # That file will have entries such as:
1468
+ #
1469
+ # 28.11.2016 | 3.0 | 6.0 | 1 | UniWien | M | 330011 | Zell- und Molekularbiologie
1470
+ #
1471
+ # So we can pick field number 6. If that field has an upcased 'M' then
1472
+ # it qualifies.
1473
+ #
1474
+ # To invoke this method from the commandline, do:
1475
+ # emo --show-only-master-lectures
1476
+ # ========================================================================= #
1477
+ def show_only_master_lectures
1478
+ _ = @dataset.select {|array|
1479
+ bachelor_or_master_curriculum = array[5].strip
1480
+ bachelor_or_master_curriculum.include? 'M'
1481
+ }
1482
+ total_ects_points = 0
1483
+ e
1484
+ _.each_with_index {|lecture_data, index|
1485
+ index += 1
1486
+ n_ects = lecture_data[2]
1487
+ total_ects_points += n_ects.to_f
1488
+ name_of_the_lecture = lecture_data.last
1489
+ leistung_erbracht_am = lecture_data.first
1490
+ which_university = mediumturquoise(lecture_data[4])
1491
+ show_number_then_name_of_the_lecture_then_n_ECTS_points_then_leistung_erbracht_then_which_university(
1492
+ index, name_of_the_lecture, n_ects, leistung_erbracht_am, which_university
1493
+ )
1494
+ }
1495
+ report_total_amount_of_ects_points(total_ects_points, :master)
1496
+ end
1497
+
1498
+ # ========================================================================= #
1499
+ # === show_only_bachelor_lectures
1500
+ #
1501
+ # As the variant for master lectures, just for bachelor lectures.
1502
+ #
1503
+ # To invoke it, do:
1504
+ # emo --show-only-bachelor-lectures
1505
+ # ========================================================================= #
1506
+ def show_only_bachelor_lectures
1507
+ _ = @dataset.select {|array|
1508
+ bachelor_or_master_curriculum = array[5].strip
1509
+ bachelor_or_master_curriculum.include? 'B'
1510
+ }
1511
+ total_ects_points = 0
1512
+ e
1513
+ _.each_with_index {|lecture_data, index|
1514
+ index += 1
1515
+ n_ects = lecture_data[2]
1516
+ total_ects_points += n_ects.to_f
1517
+ name_of_the_lecture = lecture_data.last
1518
+ leistung_erbracht_am = lecture_data.first
1519
+ which_university = mediumturquoise(lecture_data[4])
1520
+ show_number_then_name_of_the_lecture_then_n_ECTS_points_then_leistung_erbracht_then_which_university(
1521
+ index, name_of_the_lecture, n_ects, leistung_erbracht_am, which_university
1522
+ )
1523
+ }
1524
+ report_total_amount_of_ects_points(total_ects_points, :bachelor)
1525
+ end
1526
+
1527
+ # ========================================================================= #
1528
+ # === report_total_amount_of_ects_points
1529
+ # ========================================================================= #
1530
+ def report_total_amount_of_ects_points(
1531
+ total_ects_points,
1532
+ bachelor_or_master = :bachelor,
1533
+ ljust_to_use = 41 # Reason for this value is so that it aligns.
1534
+ )
1535
+ bachelor_or_master = bachelor_or_master.to_s.capitalize # Capitalization is nicer.
1536
+ e
1537
+ e 'Total ECTS points from '+bachelor_or_master+' lectures: '.
1538
+ ljust(ljust_to_use)+
1539
+ slateblue(total_ects_points.to_s+' ECTS')
1540
+ e
1541
+ end
1542
+
1543
+ # ========================================================================= #
1544
+ # === show_number_then_name_of_the_lecture_then_n_ECTS_points_then_leistung_erbracht_then_which_university
1545
+ #
1546
+ # This long compound method is only used from within the following two
1547
+ # methods:
1548
+ #
1549
+ # show_only_bachelor_lectures
1550
+ # show_only_master_lectures
1551
+ #
1552
+ # ========================================================================= #
1553
+ def show_number_then_name_of_the_lecture_then_n_ECTS_points_then_leistung_erbracht_then_which_university(
1554
+ index, name_of_the_lecture, n_ects, leistung_erbracht_am, which_university
1555
+ )
1556
+ e lightgreen((index.to_s+')').rjust(6))+' '+
1557
+ orange(name_of_the_lecture.ljust(74))+' '+
1558
+ slateblue(n_ects.to_s+' ECTS')+crimson(
1559
+ ' '+leistung_erbracht_am.to_s
1560
+ )+' '+which_university
1561
+ end
1562
+
1563
+ # ========================================================================= #
1564
+ # === show_only_exams_past_this_date
1565
+ #
1566
+ # The argument to this method should be the starting time, the day at
1567
+ # which you wish to keep track of exams made afterwards.
1568
+ #
1569
+ # To invoke this method, do:
1570
+ # emo "since 10.02.2014"
1571
+ # ========================================================================= #
1572
+ def show_only_exams_past_this_date(this_date)
1573
+ unless this_date.include? '.'
1574
+ this_date.prepend('01.01.') # In this case, we assume this to mean the first January.
1575
+ end
1576
+ # ======================================================================= #
1577
+ # The variable this_date will be something like "18.08.2013".
1578
+ # ======================================================================= #
1579
+ opne 'Showing only passed exams past the date '+simp(this_date.to_s)+'.'
1580
+ # ======================================================================= #
1581
+ # Convert a String into a time object.
1582
+ # ======================================================================= #
1583
+ this_date = Time.parse(this_date) if this_date.is_a? String
1584
+ a = this_date # Shorter to type. :)
1585
+ _ = dataset?
1586
+ new_array_with_matches = []
1587
+ _.each {|entry|
1588
+ # ======================================================================= #
1589
+ # We simply assume the first day of the given month next.
1590
+ # ======================================================================= #
1591
+ first = '01.'+entry.first.strip
1592
+ date = Time.parse(first) # Must insert date here.
1593
+ b = date
1594
+ if a < b
1595
+ new_array_with_matches << entry # Only add entries that are relevant.
1596
+ end
1597
+ }
1598
+ reset_main_hash # Reset for a clean state again.
1599
+ sanitize_dataset(new_array_with_matches, :leave_time_entry_alone)
1600
+ end
1601
+
1602
+ # ========================================================================= #
1603
+ # === show_only_exams_at_the_tu
1604
+ #
1605
+ # Show only exams at the TU.
1606
+ # ========================================================================= #
1607
+ def show_only_exams_at_the_tu
1608
+ opne 'Showing all exams passed at the TU.'
1609
+ _ = dataset?.select {|entry|
1610
+ name_of_university = entry[4]
1611
+ (name_of_university.strip.downcase.start_with? 'tu')
1612
+ }
1613
+ reset_main_hash
1614
+ sanitize_dataset(_, :leave_time_entry_alone)
1615
+ end
1616
+
1617
+ # ========================================================================= #
1618
+ # === do_show_the_grades_statistics
1619
+ #
1620
+ # Show all grade statistics.
1621
+ #
1622
+ # Invocation example:
1623
+ # emo --grades
1624
+ # ========================================================================= #
1625
+ def do_show_the_grades_statistics
1626
+ _ = dataset?
1627
+ # ======================================================================= #
1628
+ # The dataset will have entries such as:
1629
+ # ["05.1998","2.0"," xxx","4","UniWien"," D "," 854623 ","1998W","Biologische Physik II (Physik für Biologen II)"]
1630
+ # So for our purpose, we are only interested in entry at position
1631
+ # 2, 3 and 4.
1632
+ # ======================================================================= #
1633
+ hash_containing_the_relevant_entries = {}
1634
+ # ======================================================================= #
1635
+ # The following data structures are of interest:
1636
+ # - How many exams were passed for this grade
1637
+ # - The total amount of ECTS points passed
1638
+ # - The total amount of hours passed
1639
+ # ======================================================================= #
1640
+ hash_containing_the_relevant_entries[1] = [0,0,0]
1641
+ hash_containing_the_relevant_entries[2] = [0,0,0]
1642
+ hash_containing_the_relevant_entries[3] = [0,0,0]
1643
+ hash_containing_the_relevant_entries[4] = [0,0,0]
1644
+ # ======================================================================= #
1645
+ # Iterate over the dataset.
1646
+ # ======================================================================= #
1647
+ _.each {|line|
1648
+ this_grade = line[3].to_i
1649
+ if this_grade == 0
1650
+ # pp 'DEBUG'; pp line # For entries that have a '+' evaluation rather.
1651
+ else
1652
+ n_ects_points = line[1].to_f
1653
+ n_hours = line[2].to_f
1654
+ array = hash_containing_the_relevant_entries[this_grade]
1655
+ array[0] += 1
1656
+ array[1] += n_ects_points # For ECTS points.
1657
+ array[2] += n_hours # For Semesterwochenstunden.
1658
+ hash_containing_the_relevant_entries[this_grade] = array
1659
+ end
1660
+ }
1661
+ e
1662
+ e lightgreen('The grades that were passed successfully, are as follows:')
1663
+ e
1664
+ average_grade = 0
1665
+ average_grade_weighted_by_ects_points = 0
1666
+ n_total_exams = hash_containing_the_relevant_entries.values.map {|array|
1667
+ array.first
1668
+ }.sum
1669
+ hash_containing_the_relevant_entries.each_pair {|grade, array_dataset|
1670
+ n_exams_passed = array_dataset.first
1671
+ total_n_ects_points = array_dataset[1]
1672
+ total_n_hours = array_dataset.last
1673
+ n_percent = (n_exams_passed.to_i * 100 / n_total_exams).round(3).to_s
1674
+ e "For the grade #{simp(grade)} #{crimson(n_exams_passed.to_s)} "\
1675
+ "exams were passed successfully. (#{crimson(n_percent.to_s+'%')})"
1676
+ e " n ECTS points: #{mediumorchid(total_n_ects_points.to_s.rjust(5))}"
1677
+ e " n hours: #{mediumpurple(total_n_hours.to_s.rjust(5))}"
1678
+ e
1679
+ }
1680
+ hash = hash_containing_the_relevant_entries
1681
+ average_grade = (1 * hash[1][0]+
1682
+ 2 * hash[2][0]+
1683
+ 3 * hash[3][0]+
1684
+ 4 * hash[4][0])
1685
+ total_n_ects_points = hash[1][1].to_f+
1686
+ hash[2][1].to_f+
1687
+ hash[3][1].to_f+
1688
+ hash[4][1].to_f
1689
+ average_grade_weighted_by_ects_points = (
1690
+ 1 * hash[1][1].to_f+
1691
+ 2 * hash[2][1].to_f+
1692
+ 3 * hash[3][1].to_f+
1693
+ 4 * hash[4][1].to_f
1694
+ )
1695
+ average_grade_weighted_by_ects_points =
1696
+ average_grade_weighted_by_ects_points.to_f / total_n_ects_points.to_f # Gesamtzahl an ECTS
1697
+ average_grade = average_grade.to_f / (
1698
+ hash[1][0]+
1699
+ hash[2][0]+
1700
+ hash[3][0]+
1701
+ hash[4][0]
1702
+ ) # Have to divide it by the amount of exams.
1703
+ average_grade = average_grade.round(2)
1704
+ # ======================================================================= #
1705
+ # Next, show some statistics.
1706
+ # ======================================================================= #
1707
+ e 'This means that the average grade is: '+
1708
+ slateblue(average_grade.to_s)
1709
+ e 'And the average grade, weighted per single (1.0) ECTS point, is: '+
1710
+ lightblue(average_grade_weighted_by_ects_points.round(2).to_s)
1711
+ e
1712
+ end
1713
+
1714
+ # ========================================================================= #
1715
+ # === show_how_many_exams_we_have_passed_in_this_curriculum
1716
+ #
1717
+ # This method will show how many exams we have already passed for
1718
+ # a given curriculum xyz.
1719
+ #
1720
+ # To invoke this, do:
1721
+ #
1722
+ # emo --agrarwissenschaften
1723
+ #
1724
+ # ========================================================================= #
1725
+ def show_how_many_exams_we_have_passed_in_this_curriculum(i)
1726
+ require 'studium/utility_scripts/show_lectures_on_the_commandline/show_lectures_on_the_commandline.rb'
1727
+ i = i.to_s.delete('_')
1728
+ _ = ::Studium::ShowLecturesOnTheCommandline.new(
1729
+ i, :do_not_run_yet
1730
+ )
1731
+ _.do_not_report_anything
1732
+ _.iterate_over_the_lectures
1733
+ _.report_how_many_exams_have_been_passed_already
1734
+ end
1735
+
1736
+ # ========================================================================= #
1737
+ # === set_n_exams_in_total_passed
1738
+ # ========================================================================= #
1739
+ def set_n_exams_in_total_passed(i)
1740
+ @n_exams_in_total_passed = i.to_f
1741
+ end
1742
+
1743
+ # ========================================================================= #
1744
+ # === set_n_ects_points_in_total
1745
+ # ========================================================================= #
1746
+ def set_n_ects_points_in_total(i)
1747
+ @n_ects_points_in_total = i.to_f
1748
+ end
1749
+
1750
+ # ========================================================================= #
1751
+ # === determine_n_ects_points_in_total
1752
+ #
1753
+ # The main Hash will look like this:
1754
+ #
1755
+ # {"07.2018"=>[9.0, 14.0, ["+", "4", "1", "1"], "uniwien", 4]
1756
+ #
1757
+ # The relevant ECTS entries are in the value part, at the second
1758
+ # position, so [1].
1759
+ # ========================================================================= #
1760
+ def determine_n_ects_points_in_total
1761
+ n_ects_points = @hash.values.map {|entry| entry[1] }.sum
1762
+ set_n_ects_points_in_total(n_ects_points)
1763
+ end
1764
+
1765
+ # ========================================================================= #
1766
+ # === determine_n_exams_in_total_were_passed
1767
+ # ========================================================================= #
1768
+ def determine_n_exams_in_total_were_passed
1769
+ n_exams = @hash.values.map {|entry| entry.last }.sum
1770
+ set_n_exams_in_total_passed(n_exams)
1771
+ end
1772
+
1773
+ # ========================================================================= #
1774
+ # === show_the_years_in_a_short_table_overview
1775
+ #
1776
+ # To invoke this method, do:
1777
+ # emo --years
1778
+ # ========================================================================= #
1779
+ def show_the_years_in_a_short_table_overview
1780
+ total_ects = 0
1781
+ _ = dataset? # Prepare the dataset a bit.
1782
+ _.map! {|inner_array|
1783
+ n_ects_points = inner_array[2] # Grab the amount of ECTS of this exam.
1784
+ [inner_array[0].split('.').last, n_ects_points]
1785
+ }
1786
+ # ======================================================================= #
1787
+ # Determine the current year automatically.
1788
+ # ======================================================================= #
1789
+ current_year = Date.today.year # 2017
1790
+ total_ects_points_in_that_year = 0
1791
+ e
1792
+ e steelblue('Year')+
1793
+ sfancy(' n ECTS points')
1794
+ show_colourized_line
1795
+ _.each {|year, n_ects_points|
1796
+ year = year.to_i
1797
+ n_ects_points = n_ects_points.to_f
1798
+ total_ects += n_ects_points
1799
+ if current_year == year
1800
+ total_ects_points_in_that_year += n_ects_points
1801
+ else
1802
+ e ' '+
1803
+ steelblue(( (current_year.to_s+': ') ).ljust(15))+
1804
+ sfancy(total_ects_points_in_that_year.to_s.rjust(5)+' ECTS points')
1805
+ total_ects_points_in_that_year = 0
1806
+ current_year = year
1807
+ total_ects_points_in_that_year += n_ects_points
1808
+ end
1809
+ }
1810
+ show_colourized_line
1811
+ e (' ' * 16)+sfancy(total_ects.to_s+' ECTS points')
1812
+ e
1813
+ end
1814
+
1815
+ # ========================================================================= #
1816
+ # === show_colourized_line
1817
+ # ========================================================================= #
1818
+ def show_colourized_line(n_times = 34)
1819
+ e simp('-' * n_times)
1820
+ end
1821
+
1822
+ # ========================================================================= #
1823
+ # === show_best_months
1824
+ #
1825
+ # This method will show the best months, sorted. Best comes first.
1826
+ #
1827
+ # Invocation example:
1828
+ #
1829
+ # emo --show-best-months
1830
+ #
1831
+ # ========================================================================= #
1832
+ def show_best_months(
1833
+ do_show_n_months = @show_n_best_months
1834
+ )
1835
+ opne 'Showing the '+slateblue(do_show_n_months.to_s)+' best '\
1836
+ 'months next, sorted by n ECTS points passed:'
1837
+ e
1838
+ hash_month_statistics = {}
1839
+ _ = @hash.sort_by {|key, inner_array|
1840
+ n_ECTS_points = inner_array[1].to_f
1841
+ n_ECTS_points
1842
+ }.reverse
1843
+ # ======================================================================= #
1844
+ # Next we must determine the sub-array which we will display.
1845
+ # ======================================================================= #
1846
+ array_to_display = []
1847
+ _.each {|month, inner_array|
1848
+ array_to_display << [ month, inner_array[1].to_f ]
1849
+ }
1850
+ # ======================================================================= #
1851
+ # How many months to analyze will be determined next:
1852
+ # ======================================================================= #
1853
+ array_to_display = array_to_display[0..(do_show_n_months - 1)]
1854
+ # ======================================================================= #
1855
+ # Now we have our dataset - array_to_display keeps track of it.
1856
+ # ======================================================================= #
1857
+ exam_number_n = 0 # <- Keep track of which exam is in use.
1858
+ array_to_display.each {|month, n_ECTS_points_passed|
1859
+ # ===================================================================== #
1860
+ # The dataset may look like this:
1861
+ #
1862
+ # [["01.2017", 41.0],
1863
+ # ["06.2015", 35.0],
1864
+ #
1865
+ # ===================================================================== #
1866
+ exam_number_n += 1
1867
+ left_pad = ((exam_number_n.to_s+')').rjust(5)).ljust(6)
1868
+ # ======================================================================= #
1869
+ # Report this to the user:
1870
+ # ======================================================================= #
1871
+ rounded_n_ECTS_points_passed = n_ECTS_points_passed.to_s.to_f.round(1)
1872
+ e yellow(left_pad)+'In the month '+
1873
+ sfancy(month)+', '+
1874
+ violet(rounded_n_ECTS_points_passed.to_s.rjust(4))+
1875
+ ' ECTS points were completed.'
1876
+ # ======================================================================= #
1877
+ # Also add to the hash that keeps track about the month-statistics.
1878
+ # ======================================================================= #
1879
+ this_month = month.split('.').first.to_i # <- Example input: "01.2017"
1880
+ this_month = Studium::MONTH_NUMBER_TO_MONTH_NAME[this_month]
1881
+ hash = {
1882
+ :n_ects => n_ECTS_points_passed,
1883
+ :n_times_mentioned => 1
1884
+ }
1885
+ if hash_month_statistics.has_key? this_month
1886
+ hash_month_statistics[this_month][:n_ects] += n_ECTS_points_passed
1887
+ hash_month_statistics[this_month][:n_times_mentioned] += 1
1888
+ else
1889
+ hash_month_statistics[this_month] = hash
1890
+ end
1891
+ }
1892
+ e
1893
+ # ======================================================================= #
1894
+ # Next, we will also show some month statistics.
1895
+ # ======================================================================= #
1896
+ colourized_n_best_months = orange(do_show_n_months)
1897
+ opne "The best #{colourized_n_best_months} (top) months "\
1898
+ "seem to be the following ones:"
1899
+ e
1900
+ _ = hash_month_statistics
1901
+ # ======================================================================= #
1902
+ # The variable name_of_the_month keeps track of the month at hand,
1903
+ # e. g. "January" or "March".
1904
+ # ======================================================================= #
1905
+ _ = _.sort_by {|name_of_the_month, hash_containing_n_ects_and_n_times_mentioned|
1906
+ n_ects = hash_containing_n_ects_and_n_times_mentioned[:n_ects]
1907
+ n_ects
1908
+ }.reverse
1909
+ counter = 0
1910
+ # ======================================================================= #
1911
+ # Now we have the entry properly sorted. We will display only up to
1912
+ # n times specified as above (e. g. 8 times right now).
1913
+ # ======================================================================= #
1914
+ _.each {|name_of_the_month, hash_containing_n_ects_and_n_times_mentioned|
1915
+ next if counter > 7 # <- Sync it with the above value of 8.
1916
+ n_ects = hash_containing_n_ects_and_n_times_mentioned[:n_ects]
1917
+ n_times_mentioned = hash_containing_n_ects_and_n_times_mentioned[:n_times_mentioned]
1918
+ counter += 1
1919
+ e ' '+
1920
+ sfancy((name_of_the_month+':').ljust(12))+
1921
+ orange(n_times_mentioned.to_s.rjust(2))+ # <- n_times mentioned
1922
+ olivedrab(' (ECTS in total: ')+
1923
+ colourize_ects_points(n_ects.to_s.rjust(5))+
1924
+ olivedrab('; average ECTS in that month: ')+
1925
+ colourize_ects_points(
1926
+ (n_ects.to_f / n_times_mentioned.to_i).round(1).to_s.rjust(4)
1927
+ )+
1928
+ olivedrab(')')
1929
+ }
1930
+ e
1931
+ end
1932
+
1933
+ # ========================================================================= #
1934
+ # === show_total_summary_for_year_hours_ects_n_exams
1935
+ #
1936
+ # This method will show the total summary for a given year.
1937
+ # ========================================================================= #
1938
+ def show_total_summary_for_year_hours_ects_n_exams(
1939
+ last_year,
1940
+ total_n_hours_passed_in_this_year,
1941
+ total_n_ects_passed_in_this_year,
1942
+ total_n_exams_passed_in_this_year,
1943
+ optional_average_grade_per_exam = nil # The average grade per exam in a given year. Optional entr.y
1944
+ )
1945
+ if @show_only_this_year and
1946
+ @show_only_this_year.include?('-') and
1947
+ @show_only_this_year.split('-').last.to_i < last_year
1948
+ # This is the case here when we show a range.
1949
+ elsif @show_only_this_year and
1950
+ (@show_only_this_year != last_year)
1951
+ else
1952
+ e # And a newline too.
1953
+ result = 'Total Summary in '+sfancy(last_year.to_s)+': '+
1954
+ # Add n_hours next.
1955
+ colourize_hours(
1956
+ total_n_hours_passed_in_this_year.to_s.rjust(4)
1957
+ )+' '
1958
+ # ======================================================================= #
1959
+ # Add n_ECTS next.
1960
+ # ======================================================================= #
1961
+ if show_ects_points?
1962
+ result << colourize_ects(
1963
+ total_n_ects_passed_in_this_year.to_f.to_s.rjust(5)+
1964
+ ' ECTS passed'
1965
+ )
1966
+ end
1967
+ # ======================================================================= #
1968
+ # We will use papayawhip here instead.
1969
+ # ======================================================================= #
1970
+ result << colourize_n_exams(' (n exams passed that year: '+
1971
+ total_n_exams_passed_in_this_year.to_s.rjust(3)+')',
1972
+ :mediumseagreen
1973
+ )
1974
+ e result
1975
+ if @show_yearly_average_grades and optional_average_grade_per_exam
1976
+ if block_given?
1977
+ yielded = yield
1978
+ if yielded.is_a? Hash
1979
+ if yielded.has_key? :exclude_n_exams_from_the_grade_list
1980
+ total_n_exams_passed_in_this_year -= yielded[:exclude_n_exams_from_the_grade_list].to_i
1981
+ end
1982
+ end
1983
+ end
1984
+ _ = (
1985
+ optional_average_grade_per_exam.to_f / total_n_exams_passed_in_this_year.to_f
1986
+ ).round(2)
1987
+ _ = _.to_s.ljust(4,'0')
1988
+ e 'The average grade of the exams passed in this year is: '+
1989
+ sfancy(_)
1990
+ end
1991
+ end
1992
+ end
1993
+
1994
+ # ========================================================================= #
1995
+ # === show_only_exams_at_the_boku
1996
+ #
1997
+ # Show only exams at the BOKU.
1998
+ # ========================================================================= #
1999
+ def show_only_exams_at_the_boku
2000
+ opne 'Showing all exams passed at the BOKU.'
2001
+ _ = dataset?.select {|entry|
2002
+ name_of_university = entry[4]
2003
+ (name_of_university.strip.downcase == 'boku')
2004
+ }
2005
+ reset_main_hash
2006
+ sanitize_dataset(_, :leave_time_entry_alone)
2007
+ end
2008
+
2009
+ # ========================================================================= #
2010
+ # === show_n_exams_passed_per_month (report tag)
2011
+ #
2012
+ # This is the main report-method for this class.
2013
+ #
2014
+ # Make sure that the input to this method is correct.
2015
+ # ========================================================================= #
2016
+ def show_n_exams_passed_per_month(
2017
+ i = @hash
2018
+ )
2019
+ month = 0
2020
+ year = 0
2021
+ n_hours = 0
2022
+ n_ECTS = 0
2023
+ grade = 0
2024
+ # ======================================================================= #
2025
+ # We must initialize some variables here.
2026
+ # ======================================================================= #
2027
+ n_exams_passed_in_this_month = 0
2028
+ total_n_ects_passed_in_this_year = 0
2029
+ total_n_hours_passed_in_this_year = 0
2030
+ total_n_exams_passed_in_this_year = 0
2031
+ total_grade_count_in_this_year = 0
2032
+ exclude_n_exams_from_the_grade_list = 0
2033
+
2034
+ last_year = LAST_YEAR # Will point to the current year actually.
2035
+ this_year = Time.now.year.to_i
2036
+ # ======================================================================= #
2037
+ # Check whether we shall only show certain grades.
2038
+ # ======================================================================= #
2039
+ if @show_only_grade_for
2040
+ opne "We will only show grades that are equal to "\
2041
+ "#{simp(@show_only_grade_for.to_s)}."
2042
+ end
2043
+ e
2044
+ opne 'We will show how many hours / ECTS we passed per '\
2045
+ 'given month and then year.'
2046
+ e
2047
+ spacer
2048
+ # ======================================================================= #
2049
+ # Header:
2050
+ # ======================================================================= #
2051
+ if @show_only_this_year and
2052
+ @show_only_this_year.include?('-') and
2053
+ @show_only_this_year.split('-').last.to_i < last_year
2054
+ # ===================================================================== #
2055
+ # In this case, do not show the last year.
2056
+ # ===================================================================== #
2057
+ elsif @show_only_this_year and
2058
+ (@show_only_this_year != last_year) and
2059
+ (this_year != last_year)
2060
+ # ===================================================================== #
2061
+ # In this case we will also not show the last year.
2062
+ # ===================================================================== #
2063
+ else # This here is the main clause - most conditions lead to this case.
2064
+ output_colourized_year_and_colourized_hours(last_year)
2065
+ end
2066
+ # ======================================================================= #
2067
+ # We iterate through our hash. Each entry processed through .each
2068
+ # is the dataset for a whole month.
2069
+ #
2070
+ # The entries are:
2071
+ #
2072
+ # - On the left side, the month.year entry.
2073
+ #
2074
+ # - On the right side, an Array with n hours, n ects points,
2075
+ # the grade, n exams passed and the university .
2076
+ # ======================================================================= #
2077
+ i.each {|month_year, n_hours_n_ECTS_grade_university_n_exams_passed|
2078
+ month, year = month_year.split('.').map(&:to_i)
2079
+ # ===================================================================== #
2080
+ # First we deconstruct the information stored in our Array:
2081
+ # n_hours | n_ECTS | grade | university | n_exams_passed
2082
+ # ===================================================================== #
2083
+ n_hours, n_ECTS, grade, _university, n_exams_passed_in_this_month =
2084
+ n_hours_n_ECTS_grade_university_n_exams_passed
2085
+ # ===================================================================== #
2086
+ # Currently, the grade is not output as it is not so important. It
2087
+ # can, however had, be used for showing the average grade per year.
2088
+ # ===================================================================== #
2089
+ # Next, the case will be handled when we only show exams that have a
2090
+ # specific grade.
2091
+ # ===================================================================== #
2092
+ if @show_only_grade_for
2093
+ next unless grade == @show_only_grade_for
2094
+ end
2095
+ # ===================================================================== #
2096
+ # Switch to another year in that event.
2097
+ # ===================================================================== #
2098
+ if year != last_year
2099
+ # =================================================================== #
2100
+ # Show the total summary per given year. The last entry showing the
2101
+ # average grade is optional.
2102
+ # =================================================================== #
2103
+ show_total_summary_for_year_hours_ects_n_exams(
2104
+ last_year, total_n_hours_passed_in_this_year,
2105
+ total_n_ects_passed_in_this_year,
2106
+ total_n_exams_passed_in_this_year,
2107
+ total_grade_count_in_this_year
2108
+ ) {{ exclude_n_exams_from_the_grade_list: exclude_n_exams_from_the_grade_list }}
2109
+ # =================================================================== #
2110
+ # Reset various variables next, in order to prepare for the dataset
2111
+ # from a new year.
2112
+ # =================================================================== #
2113
+ total_n_ects_passed_in_this_year = 0
2114
+ total_n_hours_passed_in_this_year = 0
2115
+ total_n_exams_passed_in_this_year = 0
2116
+ total_grade_count_in_this_year = 0
2117
+ exclude_n_exams_from_the_grade_list = 0
2118
+ # =================================================================== #
2119
+ # Show the spacer after the summary.
2120
+ # =================================================================== #
2121
+ spacer unless @show_only_this_year and (@show_only_this_year != last_year)
2122
+ # =================================================================== #
2123
+ # Red year.
2124
+ # =================================================================== #
2125
+ output_colourized_year_and_colourized_hours(year)
2126
+ # =================================================================== #
2127
+ # New year starts here. We will display end-of-year stuff,
2128
+ # before resetting other counters.
2129
+ # =================================================================== #
2130
+ last_year = year
2131
+ end
2132
+ total_n_hours_passed_in_this_year += n_hours
2133
+ @n_hours_passed_in_total += n_hours
2134
+ total_n_ects_passed_in_this_year += n_ECTS
2135
+ @n_ects_points_in_total += n_ECTS
2136
+ total_n_exams_passed_in_this_year += n_exams_passed_in_this_month
2137
+ @n_exams_in_total_passed += n_exams_passed_in_this_month.to_i
2138
+ # ===================================================================== #
2139
+ # Before we can add to the total grade count in this year, we must
2140
+ # first ensure that the input is not a '+', since this would mean
2141
+ # passing an exam without getting a grade such as 1, 2, 3, 4 or 5.
2142
+ #
2143
+ # Note that grade is an Array.
2144
+ # ===================================================================== #
2145
+ if grade.include? '+'
2146
+ exclude_n_exams_from_the_grade_list += grade.count('+')
2147
+ grade.reject! {|entry| entry == '+' }
2148
+ end
2149
+ # ===================================================================== #
2150
+ # Next, we can push it into the variable total_grade_count_in_this_year
2151
+ # ===================================================================== #
2152
+ add_this_number = grade.map(&:to_i).sum
2153
+ total_grade_count_in_this_year += add_this_number
2154
+ # ===================================================================== #
2155
+ # We can always display the dataset for the given month.
2156
+ # ===================================================================== #
2157
+ report_month_year_hours_ects_n_exams_passed_in_this_month(
2158
+ month, year, n_hours, n_ECTS, n_exams_passed_in_this_month
2159
+ )
2160
+ }
2161
+ # ======================================================================= #
2162
+ # Must display it one more time, for the last year:
2163
+ # ======================================================================= #
2164
+ show_total_summary_for_year_hours_ects_n_exams(
2165
+ last_year,
2166
+ total_n_hours_passed_in_this_year,
2167
+ total_n_ects_passed_in_this_year,
2168
+ total_n_exams_passed_in_this_year,
2169
+ total_grade_count_in_this_year
2170
+ ) {{ exclude_n_exams_from_the_grade_list: exclude_n_exams_from_the_grade_list }}
2171
+ # ======================================================================= #
2172
+ # Last but not least, we also say how many exams we have passed
2173
+ # in total, and how many ECTS points these are.
2174
+ # ======================================================================= #
2175
+ e
2176
+ ljust_it_n_times = :default
2177
+ report_how_many_exams_were_passed_in_total(@n_exams_in_total_passed, ljust_it_n_times)
2178
+ if show_ects_points? # We here will also assume that the user wants to show the amount of hours as well.
2179
+ # ===================================================================== #
2180
+ # Hours, total ects and ects-per-passed-exam:
2181
+ # ===================================================================== #
2182
+ ects_per_exams_passed = # This is: total ects / n_exams
2183
+ (
2184
+ @n_ects_points_in_total.to_f / @n_exams_in_total_passed.to_f
2185
+ ).round(2)
2186
+ report_how_many_hours_were_passed_in_total(
2187
+ @n_hours_passed_in_total, ljust_it_n_times
2188
+ )
2189
+ report_how_many_ects_points_have_been_gathered_so_far
2190
+ report_how_many_of_these_ects_points_required_mandatory_presence(
2191
+ @n_ects_points_belonging_to_mandatory_presence_courses
2192
+ )
2193
+ if @show_average_ects_passed_per_exam
2194
+ report_the_average_amount_of_ects_per_passed_exam(
2195
+ ects_per_exams_passed, ljust_it_n_times
2196
+ )
2197
+ end
2198
+ report_the_average_grade(ljust_it_n_times)
2199
+ end
2200
+ end; alias report_main_hash show_n_exams_passed_per_month # === report_main_hash
2201
+ alias report show_n_exams_passed_per_month # === report
2202
+
2203
+ # ========================================================================= #
2204
+ # === report_how_many_of_these_ects_points_required_mandatory_presence
2205
+ #
2206
+ # Report how many ECTS points have been passed that required a
2207
+ # mandatory presence (aka "prüfungsimmanent" in german).
2208
+ # ========================================================================= #
2209
+ def report_how_many_of_these_ects_points_required_mandatory_presence(
2210
+ n_ects_points_in_mandatory_presence_courses =
2211
+ Studium.n_ects_points_in_mandatory_presence_courses,
2212
+ n_ljust = 77
2213
+ )
2214
+ if n_ljust == :default
2215
+ n_ljust = 77
2216
+ end
2217
+ n_total_ects = @n_ects_points_in_total.to_f
2218
+ percentage_value = (
2219
+ n_ects_points_in_mandatory_presence_courses.to_f * 100
2220
+ ) / n_total_ects
2221
+ rounded_percentage_value = percentage_value.round(2)
2222
+ e (
2223
+ "Of these, #{slategray('n ECTS points')} are \"prüfungsimmanent\": "
2224
+ ).ljust(n_ljust)+
2225
+ sfancy(
2226
+ n_ects_points_in_mandatory_presence_courses.to_s.rjust(5)
2227
+ )+
2228
+ orange(' ('+rounded_percentage_value.to_s+'%)')
2229
+ end
2230
+
2231
+ # ========================================================================= #
2232
+ # === report_the_average_grade
2233
+ # ========================================================================= #
2234
+ def report_the_average_grade(
2235
+ n_ljust = 76,
2236
+ n_rjust = 4
2237
+ )
2238
+ if n_ljust == :default
2239
+ n_ljust = 76
2240
+ end
2241
+ e "The #{slategray('average grade')} for these exams is: ".ljust(n_ljust+3)+
2242
+ sfancy(
2243
+ average_grade.to_s.rjust(n_rjust)
2244
+ )
2245
+ end
2246
+
2247
+ # ========================================================================= #
2248
+ # === report_how_many_ects_points_have_been_gathered_so_far
2249
+ # ========================================================================= #
2250
+ def report_how_many_ects_points_have_been_gathered_so_far(
2251
+ n_ljust = 52
2252
+ )
2253
+ e "In total, #{slategray('n ECTS points')} have been "\
2254
+ "gathered so far: ".ljust(n_ljust)+
2255
+ "#{sfancy(@n_ects_points_in_total.to_s)}"
2256
+ end
2257
+
2258
+ # ========================================================================= #
2259
+ # === report_the_average_amount_of_ects_per_passed_exam
2260
+ # ========================================================================= #
2261
+ def report_the_average_amount_of_ects_per_passed_exam(
2262
+ ects_per_exams_passed = calculate_the_average_amount_per_passed_exam,
2263
+ ljust_n_times = 76,
2264
+ rjust_n_times = 12
2265
+ )
2266
+ if ljust_n_times == :default
2267
+ ljust_n_times = 76
2268
+ end
2269
+ left_padded_side = "On average, the "\
2270
+ "#{slategray('ECTS per passed exam')} "\
2271
+ "are: ".ljust(ljust_n_times)
2272
+ e left_padded_side+
2273
+ sfancy(
2274
+ (ects_per_exams_passed.to_s+' ECTS').rjust(rjust_n_times)
2275
+ )
2276
+ end
2277
+
2278
+ # ========================================================================= #
2279
+ # === show_the_summary
2280
+ #
2281
+ # To use this method from the commandline, do:
2282
+ #
2283
+ # emo --summary
2284
+ #
2285
+ # ========================================================================= #
2286
+ def show_the_summary
2287
+ determine_n_ects_points_in_total
2288
+ determine_n_exams_in_total_were_passed
2289
+ determine_n_hours_were_passed_in_total # <- How many hours were passed in total.
2290
+ # ======================================================================= #
2291
+ # Next report our findings:
2292
+ # ======================================================================= #
2293
+ report_how_many_exams_were_passed_in_total(@n_exams_in_total_passed)
2294
+ report_how_many_hours_were_passed_in_total
2295
+ report_how_many_ects_points_have_been_gathered_so_far
2296
+ if @show_average_ects_passed_per_exam
2297
+ report_the_average_amount_of_ects_per_passed_exam
2298
+ end
2299
+ report_the_average_grade
2300
+ end; alias show_only_the_summary show_the_summary # === show_only_the_summary
2301
+
2302
+ # ========================================================================= #
2303
+ # === determine_n_hours_were_passed_in_total
2304
+ # ========================================================================= #
2305
+ def determine_n_hours_were_passed_in_total
2306
+ i = @hash.values.map {|entry| entry[0].to_f }.sum.to_f
2307
+ @n_hours_passed_in_total = i
2308
+ end
2309
+
2310
+ # ========================================================================= #
2311
+ # === report_how_many_exams_were_passed_in_total
2312
+ # ========================================================================= #
2313
+ def report_how_many_exams_were_passed_in_total(
2314
+ i = @n_exams_in_total_passed,
2315
+ ljust_n_times = 76,
2316
+ n_rjust = 4
2317
+ )
2318
+ if ljust_n_times == :default
2319
+ ljust_n_times = 76
2320
+ end
2321
+ e (
2322
+ "In total, #{slategray('n exams')} have been passed:"
2323
+ ).ljust(ljust_n_times)+
2324
+ sfancy(i.to_s.rjust(n_rjust))
2325
+ end
2326
+
2327
+ # ========================================================================= #
2328
+ # === report_how_many_hours_were_passed_in_total
2329
+ #
2330
+ # This method will report how many hours were passed in total.
2331
+ # ========================================================================= #
2332
+ def report_how_many_hours_were_passed_in_total(
2333
+ i = @n_hours_passed_in_total,
2334
+ n_ljust = 76,
2335
+ n_rjust = 6
2336
+ )
2337
+ if n_ljust == :default
2338
+ n_ljust = 76
2339
+ end
2340
+ left_side_string = "In total, #{slategray('n hours')} were completed: ".ljust(n_ljust)
2341
+ # ======================================================================= #
2342
+ # Since as of 04.03.2020 the result is rounded, since otherwise the
2343
+ # display may include parts such as "00001", which we don't want here.
2344
+ # ======================================================================= #
2345
+ i = i.round(1) if i.is_a? Float
2346
+ e left_side_string+
2347
+ sfancy(i.to_s.rjust(n_rjust))
2348
+ end
2349
+
2350
+ # ========================================================================= #
2351
+ # === show_ects_passed_per_university
2352
+ # ========================================================================= #
2353
+ def show_ects_passed_per_university
2354
+ Studium::EctsPerUniversity.new { :sort_by_highest_first }
2355
+ end
2356
+
2357
+ # ========================================================================= #
2358
+ # === open_the_main_files_in_the_editor (open tag)
2359
+ #
2360
+ # This method bundles together some other open-related methods. It
2361
+ # should ideally come last in this file here, so that it can be
2362
+ # updated at a later time if my use case has changed.
2363
+ # ========================================================================= #
2364
+ def open_the_main_files_in_the_editor
2365
+ open_the_main_file_in_the_editor
2366
+ open_the_file_lecture_information_in_the_editor
2367
+ # open_the_menu_file_in_the_editor # Not sure if we need this.
2368
+ end
2369
+
2370
+ # ========================================================================= #
2371
+ # === run
2372
+ # ========================================================================= #
2373
+ def run
2374
+ sanitize_dataset
2375
+ check_against_menu
2376
+ report if @shall_we_report
2377
+ end
2378
+
2379
+ # ========================================================================= #
2380
+ # === Studium::ExamsPerMonth.show_passed_master_lectures
2381
+ # ========================================================================= #
2382
+ def self.show_passed_master_lectures
2383
+ Studium::ExamsPerMonth.new('--show_only_master_lectures')
2384
+ end
2385
+
2386
+ # ========================================================================= #
2387
+ # === Studium::ExamsPerMonth.show_passed_bachelor_lectures
2388
+ # ========================================================================= #
2389
+ def self.show_passed_bachelor_lectures
2390
+ Studium::ExamsPerMonth.new('--show_only_bachelor_lectures')
2391
+ end
2392
+
2393
+ # ========================================================================= #
2394
+ # === Studium::ExamsPerMonth.curricula_assigned_exams_file?
2395
+ # ========================================================================= #
2396
+ def self.curricula_assigned_exams_file?
2397
+ FILE_CURRICULA_ASSIGNED_EXAMS
2398
+ end
2399
+
2400
+ # ========================================================================= #
2401
+ # === Studium::ExamsPerMonth.menu_file?
2402
+ # ========================================================================= #
2403
+ def self.menu_file?
2404
+ MENU_FILE
2405
+ end
2406
+
2407
+ # ========================================================================= #
2408
+ # === ExamsPerMonth.main_file?
2409
+ # ========================================================================= #
2410
+ def self.main_file?
2411
+ FILE_PASSED_EXAMS_PER_MONTH # This is passed_exams_per_month.csv.
2412
+ end
2413
+
2414
+ end
2415
+
2416
+ # =========================================================================== #
2417
+ # === Studium.exams_per_month
2418
+ #
2419
+ # Easier module-method to instantiate a new ExamsPerMonth object.
2420
+ # =========================================================================== #
2421
+ def self.exams_per_month2
2422
+ ::Studium::ExamsPerMonth.new
2423
+ end; self.instance_eval { alias exams? exams_per_month2 } # === Studium.exams?
2424
+
2425
+ end
2426
+
2427
+ if __FILE__ == $PROGRAM_NAME
2428
+ Studium::ExamsPerMonth.new(ARGV)
2429
+ end # examspermonth