studium 0.13.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

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