Ein Notenprogramm (Artikel + Skript)

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
paedubucher
User
Beiträge: 28
Registriert: Donnerstag 29. Juni 2006, 18:29
Wohnort: Schweiz
Kontaktdaten:

Ein Notenprogramm (Artikel + Skript)

Beitragvon paedubucher » Samstag 5. Januar 2008, 16:40

Ich habe mir (anlässlich des Semesterendes) ein kleines Skript geschrieben, dass mir sagt, wie viel ich in der nächsten Prüfung leisten muss um auf einen bestimmten Durchschnitt zu kommen. Hier der Code:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
   
# Notenrechner - unterstützt Schüler beim Ausrechnen ihres Notendurchschnitts
# Copyright (C) 2008  Patrick Bucher

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

# Initialisierung
print "\nNotenprogramm\n", '-' * len("Notenprogramm")
noten = []

# Bisher erreichte Noten einlesen
while True:
  tmp = float(raw_input("Geben Sie eine Note ein (1 bis 6, 0 = Abbruch):\t"))
  if 1 <= tmp <= 6:
    noten.append(tmp)
  elif tmp == 0:
    break
  else:
    print "Falsche Eingabe!\n"

if not len(noten):
  exit()

# Durchschnitt ausgeben
notensumme = 0.0
for tmp in noten:
  notensumme += tmp

durchschnitt = notensumme / len(noten)
print "\nIhr aktueller Durchschnitt: %.2f\n" % durchschnitt

# Ziel-Durchschnittsnote einlesen
while True:
  target = float(raw_input("Geben Sie Ihre Ziel-Durchschnittsnote ein:\t"))
  if 1 <= target <= 6:
    break
  else:
    print "Falsche Eingabe!\n"

# Bei der nächsten Prüfung zu erreichende Note ausrechnen
todo = target * (len(noten) + 1) - notensumme

# Ausgabe
if todo > 6:
  maximal = (notensumme + 6) / (len(noten) + 1)
  print "\nZiel unerrreichbar! Maximaler Durchschnitt (mit Note 6): %.2f\n" % maximal
elif todo < 1:
  minimal = (notensumme + 1) / (len(noten) + 1)
  print "\nZiel unerreichbar!: Minimaler Durchschnitt (mit Note 1): %.2f \n"  % minimal
else:
  print "\nBei der nächsten Prüfung müssen Sie die Note %.2f erreichen!\n" % todo

raw_input()


Ein ausführlicher Artikel dazu ist hier zu finden.

Verbesserungsvorschläge? :)

Edit (Leonidas): Code-Highlighting eingeschaltet.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 5. Januar 2008, 17:03

Ohne mir das Programm genauer angesehen zu haben: Wieso liest du die Noten als Floats ein? Auf meinen Schulaufgaben standen bisher die Noten immer als Integer drauf.

Floats haben auch das Problem, dass 0.0 nicht immer gleich 0 ist. Nichtmal 0.0 == 0.0 ist mit Sicherheit gleich.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Beitragvon Hyperion » Samstag 5. Januar 2008, 17:05

*g* Nette Idee sich ein wenig unter Druck zu setzen :D

So, ne kleine Verbesserungsidee:
Wieso packst Du das nicht in eine main() Funktion?
Benutzeravatar
Hobbes Hobson
User
Beiträge: 42
Registriert: Sonntag 9. Dezember 2007, 15:24
Wohnort: Bremen

Beitragvon Hobbes Hobson » Samstag 5. Januar 2008, 17:05

Vllt möchte er dadurch eine 1- (1,3) ermöglichen.
Mephisto
User
Beiträge: 28
Registriert: Mittwoch 17. Januar 2007, 15:52

Beitragvon Mephisto » Samstag 5. Januar 2008, 17:07

Also auf meiner FH sind die Noten floats, ich nehm an bei ihm ist das auch so (weis garnicht ob das irgendwie allgemein geregelt ist). Auf jeden Fall kann auch 1.3 oder 2.7 oder sonstwas schreiben :)

greets meph
Benutzeravatar
paedubucher
User
Beiträge: 28
Registriert: Donnerstag 29. Juni 2006, 18:29
Wohnort: Schweiz
Kontaktdaten:

Beitragvon paedubucher » Samstag 5. Januar 2008, 17:21

Leonidas hat geschrieben:Ohne mir das Programm genauer angesehen zu haben: Wieso liest du die Noten als Floats ein? Auf meinen Schulaufgaben standen bisher die Noten immer als Integer drauf.


Bei uns (in der Schweiz) arbeiten alle Lehrerobjekte mit floats! :wink: Im Semesterzeugnis wird dann in der Regel auf 0.5 Notenpunkte genau gerundet.
Die skurrilste Note die ich je erhalten habe war eine theoretische 7.8829, die dann jedoch auf 6 abgerundet werden musste :D
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 5. Januar 2008, 17:28

Ok, gut, dann weiß ich das mal, danke. Trotzdem wird Zeile 30 nicht und wenn doch dann nur zufällig und nicht mit Sicherheit funktionieren.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
paedubucher
User
Beiträge: 28
Registriert: Donnerstag 29. Juni 2006, 18:29
Wohnort: Schweiz
Kontaktdaten:

Beitragvon paedubucher » Samstag 5. Januar 2008, 17:36

Leonidas hat geschrieben:Ok, gut, dann weiß ich das mal, danke. Trotzdem wird Zeile 30 nicht und wenn doch dann nur zufällig und nicht mit Sicherheit funktionieren.


Achso, jetzt verstehe ich deinen Einwand! Die Eingabe des Benutzers, die von 0 zu 0.0 konvertiert wird, wird mit dem fix codierten Wert 0 verglichen:

Code: Alles auswählen

0 == 0.0


Naja, das ist nicht wirklich schön!

Danke für den Hinweis.
Benutzeravatar
Hobbes Hobson
User
Beiträge: 42
Registriert: Sonntag 9. Dezember 2007, 15:24
Wohnort: Bremen

Beitragvon Hobbes Hobson » Samstag 5. Januar 2008, 17:38

Hast du mal ein Beispiel für 0 != 0.0 ?
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Samstag 5. Januar 2008, 17:43

Hobbes Hobson hat geschrieben:Hast du mal ein Beispiel für 0 != 0.0 ?

Code: Alles auswählen

>>> ((3.1 ** 2) - 9.61) != 0
>>> True
Benutzeravatar
Hobbes Hobson
User
Beiträge: 42
Registriert: Sonntag 9. Dezember 2007, 15:24
Wohnort: Bremen

Beitragvon Hobbes Hobson » Samstag 5. Januar 2008, 17:58

Das las ich so nicht gelten.

9.61-(3.1**2) --> -1.7763568394e-015

Er vergleicht aber 0.0 mit 0.
Benutzeravatar
paedubucher
User
Beiträge: 28
Registriert: Donnerstag 29. Juni 2006, 18:29
Wohnort: Schweiz
Kontaktdaten:

Beitragvon paedubucher » Samstag 5. Januar 2008, 18:05

Hobbes Hobson hat geschrieben:Das las ich so nicht gelten.

9.61-(3.1**2) --> -1.7763568394e-015

Er vergleicht aber 0.0 mit 0.


Wenn der Benutzer von sich aus -1.7763568394e-015 eingibt, dann müsste er in meinem Skript halt die Eingabe wiederholen. :wink:
Für mein Skript macht das keinen Unterschied, generell ist der Einwand aber sehr wohl berechtigt! Und damit man es sauber lernt, sollte man es immer richtig machen. So ist der Einwand meiner Meinung nach zu begründen.
Benutzeravatar
Hobbes Hobson
User
Beiträge: 42
Registriert: Sonntag 9. Dezember 2007, 15:24
Wohnort: Bremen

Beitragvon Hobbes Hobson » Samstag 5. Januar 2008, 19:07

Ich habe das jetzt etwas abgeändert, heißt in Funktionen gepackt.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding:  iso-8859-15 -*-
from __future__ import division

def eingabe():
  print "\nNotenprogramm\n", '-' * len("Notenprogramm")
  noten = []

  # Bisher erreichte Noten einlesen
  try:

    while True:
      tmp = raw_input("Geben Sie eine Note ein (1 bis 6, Ctrl + C = Abbruch):\t")
      print tmp
      try:
        tmp = float(tmp)
      except ValueError:
        print "Falsche Eingabe (value error)!\n"
      else:
        if 1 <= tmp <= 6:
          noten.append(tmp)
        else:
          print "Falsche Eingabe (out of range)!\n"

  except KeyboardInterrupt:
    if not noten:
      exit()
    return noten

def verarbeitung(noten):
  # Durchschnitt ausgeben
  notensumme = sum(noten)

  durchschnitt = notensumme / len(noten)
  print "\nIhr aktueller Durchschnitt: %.2f\n" % durchschnitt

  # Ziel-Durchschnittsnote einlesen


  while True:
      target = raw_input("Geben Sie Ihre Ziel-Durchschnittsnote ein:\t")
      try:
        target = float(target)
      except ValueError:
        print "Falsche Eingabe (value error)!\n"
      else:
        if 1 <= target <= 6:
          break
        else:
          print "Falsche Eingabe (out of range)!\n"

  # Bei der nächsten Prüfung zu erreichende Note ausrechnen
  todo = target * (len(noten) + 1) - notensumme

  if todo > 6: (-1,(notensumme + 6) / (len(noten) + 1))
# Ausgabe
  elif todo <1: return (-1, (notensumme + 1) / (len(noten) + 1))
  else: return 0, todo

def ausgabe((flag, resnote)):
  if flag > 0:  print "\nZiel unerrreichbar! Maximaler Durchschnitt (mit Note 6): %.2f\n" % resnote
  elif flag < 0:  print "\nZiel unerreichbar!: Minimaler Durchschnitt (mit Note 1): %.2f \n"  % resnote
  else: print "\nBei der nächsten Prüfung müssen Sie die Note %.2f erreichen!\n" % resnote

def main():
  ausgabe(verarbeitung(eingabe()))

if __name__ == '__main__':
  main()



Ist ein KeyboardInterrupt ein gängiges Mittel zum Abbruch einer Eingabe? Ich habe es immerhin so in der Schule gelernt ;)
Zuletzt geändert von Hobbes Hobson am Sonntag 6. Januar 2008, 00:43, insgesamt 1-mal geändert.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 5. Januar 2008, 19:14

Hobbes Hobson hat geschrieben:Ist ein KeyboardInterrupt ein gängiges Mittel zum Abbruch einer Eingabe? Ich habe es immerhin so in der Schule gelernt ;)

Ja.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
paedubucher
User
Beiträge: 28
Registriert: Donnerstag 29. Juni 2006, 18:29
Wohnort: Schweiz
Kontaktdaten:

Beitragvon paedubucher » Samstag 5. Januar 2008, 19:17

Danke für die Tipps! Auf Exceptions wird dann im siebten Teil meines Buches "Einführung in Python" eingegangen, im Moment bin ich noch bei der OOP. Und dann wären meine Ferien auch schon wieder zu Ende... :roll:

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder