Automatisierte Notenvergabe bei Klausuren

ToolV00.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. # Autoren: Vinzent Reiss, Nils Dohndorf(, Christian Tuemmler)
  2. # Letzte Aenderung: 27.07.2017
  3. # Funktion: Ermittlung und Speicherung der Noten einer Klausur
  4. #
  5. # genutzte Module
  6. from Tkinter import *
  7. import sys
  8. import os
  9. # Globale Variablen
  10. name = ""
  11. date = ""
  12. PunkteProAufgabe = []
  13. zaehler = 1
  14. ProzentSatz = 0
  15. Summe = 0
  16. BestehPunkte = 0
  17. minEins = 0
  18. minZwei = 0
  19. minDrei = 0
  20. Studenten = []
  21. StudentenPunkte = []
  22. Notenverteilung = []
  23. # Funktionsdefinitionen
  24. # interaktive Abfrage der Eckdaten (Name und Datum) der Klausur
  25. def SchluesselDatenAbfragen():
  26. def WerteUebernehmen():
  27. global name
  28. global date
  29. name = entry1.get()
  30. date = entry2.get()
  31. root.destroy()
  32. def VerbergeHilfeName():
  33. button3.config(text = "Hilfe", fg = "green", command = ZeigeHilfeName)
  34. def ZeigeHilfeName():
  35. button3.config(text = "Beachte: _ anstatt Leerzeichen", command = VerbergeHilfeName)
  36. def VerbergeHilfeDatum():
  37. button2.config(text = "Hilfe", fg = "green", command = ZeigeHilfeDatum)
  38. def ZeigeHilfeDatum():
  39. button2.config(text = "Format: DD-MM-JJJJ", command = VerbergeHilfeDatum)
  40. root = Tk()
  41. root.title("Name und Datum")
  42. Label(root, text = "Name der Klausur").grid(row = 0, column = 0)
  43. Label(root, text = "Datum der Klausur").grid(row = 1, column = 0)
  44. entry1 = Entry(root)
  45. entry2 = Entry(root)
  46. entry1.grid(row = 0, column = 1, pady = 4)
  47. entry2.grid(row = 1, column = 1, pady = 4)
  48. entry1.insert(10,"Klausur")
  49. entry2.insert(10,"01-01-2000")
  50. button1 = Button(root, text = "Uebernehmen", command = WerteUebernehmen)
  51. button2 = Button(root, text = "Hilfe", fg = "green", command = ZeigeHilfeDatum)
  52. button3 = Button(root, text = "Hilfe", fg = "green",command = ZeigeHilfeName)
  53. button1.grid(row = 3, column = 1)
  54. button2.grid(row = 1, column = 2)
  55. button3.grid(row = 0, column = 2)
  56. root.mainloop()
  57. # interktive Abfrage der fuer jede Aufgabe erreichbaren maximalen Punkte
  58. def AufgabenPunkteAbfragen():
  59. def VerbergeHilfe():
  60. button1.config(text = "Hilfe", fg = "green", command = ZeigeHilfe)
  61. def ZeigeHilfe():
  62. button1.config(text = "Anzahl Punkte fuer jede Aufgabe eintragen", command = VerbergeHilfe)
  63. def NaechsteAufgabeEinlesen():
  64. global zaehler
  65. zaehler += 1
  66. tmp = "Aufgabe",str(zaehler)
  67. label1.config(text = tmp, font = "Arial 10")
  68. entry1.delete(0,END)
  69. entry1.insert(10,"10")
  70. button1.config(text = "Hilfe", fg = "green", command = ZeigeHilfe)
  71. button2.config(text = "Weiter", command = EndeAbfragen)
  72. def EndeAbfragen():
  73. global PunkteProAufgabe
  74. if 0.0 < float(entry1.get()):
  75. PunkteProAufgabe.append(float(entry1.get()))
  76. label1.config(text = "Waren das alle Aufgaben?", font = "Arial 13 bold")
  77. button1.config(text = "Ja", fg = "black", command = root.destroy)
  78. button2.config(text = "Nein", command = NaechsteAufgabeEinlesen)
  79. root = Tk()
  80. tmp = "Aufgabe",str(zaehler)
  81. root.title("Punkte fuer einzelne Aufgaben")
  82. label1 = Label(root, text = tmp)
  83. Label(root, text = "Erreichbare Punkte").grid(row = 1, column = 0)
  84. label1.grid(row = 0, column = 1)
  85. entry1 = Entry(root)
  86. entry1.grid(row = 1, column = 1, pady = 4)
  87. entry1.insert(10,"10")
  88. button1 = Button(root, text = "Hilfe", fg = "green", command = ZeigeHilfe)
  89. button2 = Button(root, text = "Weiter", command = EndeAbfragen)
  90. button1.grid(row = 3, column = 0)
  91. button2.grid(row = 3, column = 1)
  92. root.mainloop()
  93. # interaktive Abfrage eines Prozentsatzes fuer Mindestpunktzahl zum Bestehen
  94. def MindestPunktzahlAbfragen():
  95. def WertUebernehmen():
  96. global ProzentSatz
  97. ProzentSatz = float(entry1.get())
  98. root.destroy()
  99. root = Tk()
  100. root.title("Prozentsatz zum Bestehen")
  101. Label(root, text = "Prozentsatz").grid(row = 0, column = 0)
  102. entry1 = Entry(root)
  103. entry1.grid(row = 0, column = 1)
  104. entry1.insert(10,"50")
  105. button1 = Button(root, text = "Uebernehmen", command = WertUebernehmen)
  106. button1.grid(row = 1, column = 1)
  107. root.mainloop()
  108. # errechnet die jeweiligen Mindestpunkte, die fuer die Noten 1, 2, 3 benoetigt werden
  109. def BewertungsSpiegelBerechnen():
  110. global PunkteProAufgabe
  111. global ProzentSatz
  112. global Summe
  113. global BestehPunkte
  114. global minEins
  115. global minZwei
  116. global minDrei
  117. for i in range(len(PunkteProAufgabe)):
  118. Summe += PunkteProAufgabe[i]
  119. BestehPunkte = Summe * ProzentSatz/100
  120. tmp = Summe - BestehPunkte
  121. tmp /= 4
  122. minEins = Summe - tmp
  123. minZwei = minEins - tmp
  124. minDrei = minZwei - tmp
  125. # interaktives Abfragen der individuellen Punkte der Studenten je Aufgabe
  126. def StudentenMaskeGenerieren():
  127. def VerbergeHilfe():
  128. button1.config(text = "Hilfe", fg = "green", command = ZeigeHilfe)
  129. def ZeigeHilfe():
  130. button1.config(text = "Beachte: _ anstatt Leerzeichen", command = VerbergeHilfe)
  131. def NaechstenStudentEinlesen():
  132. label1.config(text = "Name", font = "Arial 10")
  133. label2.config(text = "Matrikelnummer", font = "Arial 10")
  134. entry1.delete(0,END)
  135. entry2.delete(0,END)
  136. entry1.insert(10,"Max_Mustermann")
  137. entry2.insert(10,"9999999")
  138. for i in range(zaehler):
  139. entries[i].delete(0,END)
  140. entries[i].insert(10,PunkteProAufgabe[i])
  141. button1.config(text = "Hilfe", fg = "green", command = ZeigeHilfe)
  142. button2.config(text = "Uebernehmen", command = UebernehmeStudent)
  143. def UebernehmeStudent():
  144. global Studenten
  145. global StudentenPunkte
  146. tmpStudentenDaten = []
  147. tmpPunkte = []
  148. tmpStudentenDaten.append(int(entry2.get()))
  149. tmpStudentenDaten.append(entry1.get())
  150. Studenten.append(tmpStudentenDaten)
  151. tmpPunkte.append(int(entry2.get()))
  152. for i in range(zaehler):
  153. if float(entries[i].get()) <= float(PunkteProAufgabe[i]) and 0.0 <= float(entries[i].get()):
  154. tmpPunkte.append(float(entries[i].get()))
  155. else:
  156. tmpPunkte.append(0.0)
  157. StudentenPunkte.append(tmpPunkte)
  158. label1.config(text = "Waren das alle", font = "Arial 12 bold")
  159. label2.config(text = "Studenten?", font = "Arial 12 bold")
  160. button1.config(text = "Ja", fg = "black", command = root.destroy)
  161. button2.config(text = "Nein", command = NaechstenStudentEinlesen)
  162. global PunkteProAufgabe
  163. root = Tk()
  164. root.title("Studentendaten")
  165. label1 = Label(root, text = "Name", font = "Arial 10")
  166. label2 = Label(root, text = "Matrikelnummer", font = "Arial 10")
  167. label1.grid(row = 0, column = 0)
  168. label2.grid(row = 1, column = 0)
  169. Label(root, text = "Aufgabe").grid(row = 2, column = 0)
  170. Label(root, text = "Erreichte Punkte").grid(row = 2, column = 1)
  171. entry1 = Entry(root)
  172. entry2 = Entry(root)
  173. entry1.grid(row = 0, column = 1, pady = 4)
  174. entry2.grid(row = 1, column = 1, pady = 4)
  175. entry1.insert(10,"Max_Mustermann")
  176. entry2.insert(10,"9999999")
  177. entries = []
  178. for i in range(zaehler):
  179. tmp = str(i+1)
  180. Label(root, text = tmp).grid(row = 3+i, column = 0)
  181. entries.append(Entry(root))
  182. entries[i].grid(row = 3+i, column = 1, pady = 4)
  183. entries[i].insert(10,PunkteProAufgabe[i])
  184. button1 = Button(root, text = "Hilfe", fg = "green", command = ZeigeHilfe)
  185. button2 = Button(root, text = "Uebernehmen", command = UebernehmeStudent)
  186. button1.grid(row = 0, column = 2)
  187. button2.grid(row = 1, column = 2)
  188. root.mainloop()
  189. PunkteProAufgabe = []
  190. # Berechnung der Noten anhand der Punkte fuer jeden Studenten
  191. def GesamtNoteBerechnen():
  192. global Summe
  193. global Studenten
  194. global StudentenPunkte
  195. global minEins
  196. global minZwei
  197. global minDrei
  198. global BestehPunkte
  199. for i in range(len(Studenten)):
  200. tmpSumme = 0
  201. for j in range(1,len(StudentenPunkte[i])):
  202. tmpSumme += StudentenPunkte[i][j]
  203. if tmpSumme < BestehPunkte:
  204. Studenten[i].append(5.0)
  205. elif tmpSumme < minDrei:
  206. Studenten[i].append(4.0 + 1 - float(int(10 * ((tmpSumme - BestehPunkte) / (minDrei - BestehPunkte)))) / 10.0)
  207. elif tmpSumme < minZwei:
  208. Studenten[i].append(3.0 + 1 - float(int(10 * ((tmpSumme - minDrei) / (minZwei - minDrei)))) / 10.0)
  209. elif tmpSumme < minEins:
  210. Studenten[i].append(2.0 + 1 - float(int(10 * ((tmpSumme - minZwei) / (minEins - minZwei)))) / 10.0)
  211. else:
  212. Studenten[i].append(1.0 + 1 - float(int(10 * ((tmpSumme - minEins) / (Summe - minEins)))) / 10.0)
  213. Summe = 0
  214. minEins = 0
  215. minZwei = 0
  216. minDrei = 0
  217. BestehPunkte = 0
  218. # Berechnung der Notenverteilung
  219. def Notenspiegel():
  220. global Notenverteilung
  221. global Studenten
  222. for i in range(41):
  223. Notenverteilung.append(0)
  224. for j in range(len(Studenten)):
  225. Vergleich = Studenten[j][2]
  226. Notenverteilung[int(10*(Vergleich-1))] += 1
  227. # Ausgabe des Notenspiegels
  228. def NotenspiegelAusgabe():
  229. global Notenverteilung
  230. root = Tk()
  231. root.title("Notenspiegel")
  232. for i in range(41):
  233. farbe = "#{:s}".format(str(999999-2390*i).zfill(6))
  234. tmp = 1.0 + float(i)/10.0
  235. Label(root, text = tmp).grid(row = i, column = 0)
  236. Label(root, width = int(float(Notenverteilung[i])/float(len(Studenten))*128), background = farbe).grid(row = i, column = 1, sticky = W, pady = 4)
  237. Button(root, text = "Beenden", command = root.destroy).grid(row = 0, column = 2)
  238. root.mainloop()
  239. Notenverteilung = []
  240. # Daten an das gewaehlte Speicherformat anpassen, sodass es spaeter nicht zu
  241. # Problemen beim wiederholten Bearbeiten, durch zu lange Namen kommt
  242. def DatenAnpassen():
  243. for i in range(len(Studenten)):
  244. if Studenten[i][0] >= 10**15:
  245. Studenten[i][0] = Studenten[i][0] - (Studenten[i][0] / 10**15) * 10**15
  246. if len(Studenten[i][1]) >= 16:
  247. Studenten[i][1] = Studenten[i][1][0:15]
  248. # Die Daten im Tabellenformat:
  249. # | Matr.Nr. | Name | Note |
  250. # abspeichern
  251. def TextdateiErstellen():
  252. global Studenten
  253. global StudentenPunkte
  254. Datei = open(name, "w")
  255. Datei.write("Name der Klausur:\t%s\n" % (name))
  256. Datei.write("Datum der Klausur:\t%s\n" % (date))
  257. Datei.write("|\tMatr.-Nr.\t|\t\tName\t\t|\tNote\t|\n\n")
  258. for i in range(len(Studenten)):
  259. Datei.write("|\t%8d\t|\t%16s\t|\t%4.1f\t|\n" % (Studenten[i][0], Studenten[i][1], Studenten[i][2]))
  260. Datei.close()
  261. Studenten = []
  262. StudentenPunkte = []
  263. # ueberprueft ob die Datei im aktuellen Ordner vorhanden ist
  264. def ExistenzPruefung():
  265. global name
  266. foldercontent = os.listdir(".")
  267. if name in foldercontent:
  268. return True
  269. else:
  270. return False
  271. # liest eine existierende Klausurendatei fuer die weitere Verarbeitung aus
  272. def DatenAuslesen():
  273. Datei = open(name,"r")
  274. Datei.readline()
  275. Datei.readline()
  276. Datei.readline()
  277. Datei.readline()
  278. while True:
  279. line = Datei.readline()
  280. if not line: break
  281. tmp = line.split("|")
  282. tmp = "".join(tmp)
  283. tmp = tmp.split("\t")
  284. tmp = "".join(tmp)
  285. tmp = tmp.split()
  286. Student = []
  287. Student.append(int(tmp[0]))
  288. Student.append(tmp[1])
  289. Student.append(float(tmp[2]))
  290. Studenten.append(Student)
  291. Datei.close()
  292. # Warnhinweis ausgeben
  293. def NichtExistenzVerkuenden():
  294. root = Tk()
  295. root.title("Keine Datei gefunden")
  296. Label(root, text = "Die Datei existiert noch gar nicht!").grid()
  297. Button(root, text = "Weiter", command = root.destroy).grid()
  298. root.mainloop()
  299. # Warnhinweis ausgeben
  300. def BereitsVorhandenseinVerkuenden():
  301. root = Tk()
  302. root.title("Datei existiert bereits")
  303. Label(root, text = "Die Datei existiert bereits!").grid()
  304. Button(root, text = "Weiter", command = root.destroy).grid()
  305. root.mainloop()
  306. # manuelle Aenderungen an existierender Klausurendatei vornehmen
  307. def Aenderungen():
  308. def WerteUebernehmen():
  309. for i in range(len(Studenten)):
  310. if float(entries[i].get()) <= 5 and 1.0 <= float(entries[i].get()):
  311. Studenten[i][2] = float(entries[i].get())
  312. root.destroy()
  313. root = Tk()
  314. root.title("Studentendaten aendern")
  315. entries = []
  316. for i in range(len(Studenten)):
  317. Label(root, text = Studenten[i][0]).grid(row = i, column = 0)
  318. Label(root, text = Studenten[i][1]).grid(row = i, column = 1)
  319. entries.append(Entry(root))
  320. entries[i].grid(row = i, column = 2)
  321. entries[i].insert(10,Studenten[i][2])
  322. Button(root, text = "Uebernehmen", command = WerteUebernehmen).grid(row = 0, column = 3)
  323. root.mainloop()
  324. # Hauptmenue aufrufen
  325. def Hauptmenue():
  326. def NeueKlausur():
  327. mainroot.destroy()
  328. SchluesselDatenAbfragen()
  329. if not ExistenzPruefung():
  330. AufgabenPunkteAbfragen()
  331. MindestPunktzahlAbfragen()
  332. BewertungsSpiegelBerechnen()
  333. StudentenMaskeGenerieren()
  334. GesamtNoteBerechnen()
  335. Notenspiegel()
  336. NotenspiegelAusgabe()
  337. DatenAnpassen()
  338. TextdateiErstellen()
  339. else:
  340. BereitsVorhandenseinVerkuenden()
  341. Hauptmenue()
  342. def AlteKlausurErweitern():
  343. mainroot.destroy()
  344. SchluesselDatenAbfragen()
  345. if ExistenzPruefung():
  346. AufgabenPunkteAbfragen()
  347. MindestPunktzahlAbfragen()
  348. BewertungsSpiegelBerechnen()
  349. StudentenMaskeGenerieren()
  350. GesamtNoteBerechnen()
  351. DatenAuslesen()
  352. Notenspiegel()
  353. NotenspiegelAusgabe()
  354. DatenAnpassen()
  355. TextdateiErstellen()
  356. else:
  357. NichtExistenzVerkuenden()
  358. Hauptmenue()
  359. def AlteKlausurBearbeiten():
  360. mainroot.destroy()
  361. SchluesselDatenAbfragen()
  362. if ExistenzPruefung():
  363. DatenAuslesen()
  364. Aenderungen()
  365. DatenAnpassen()
  366. Notenspiegel()
  367. NotenspiegelAusgabe()
  368. TextdateiErstellen()
  369. else:
  370. NichtExistenzVerkuenden()
  371. Hauptmenue()
  372. mainroot = Tk()
  373. mainroot.title("Hauptmenue")
  374. button1 = Button(mainroot, text = "Neue Klausur", command = NeueKlausur)
  375. button2 = Button(mainroot, text = "Alte Klausur erweitern", command = AlteKlausurErweitern)
  376. button3 = Button(mainroot, text = "Alte Klausur bearbeiten", command = AlteKlausurBearbeiten)
  377. button4 = Button(mainroot, text = "Beenden", command = mainroot.destroy)
  378. button1.grid(row = 0, column = 0)
  379. button2.grid(row = 0, column = 1)
  380. button3.grid(row = 0, column = 2)
  381. button4.grid(row = 0, column = 3)
  382. mainroot.mainloop()
  383. # Hauptprogramm
  384. Hauptmenue()