Seite 1 von 1

keine Ausgabe???

Verfasst: Samstag 5. Mai 2012, 13:53
von JuGa2000
tja hier bin ich wieder mit meinem programm,das angeben soll, wann man halb so alt war, wie jetzt. das tuple problem hat sich jetzt gelöst, dafür kommt aber ein neues problem auf: jetzt gibt python nichts mehr aus :K :K ? jetzt habe ich das so geschrieben.:

Code: Alles auswählen

#Unterprogramm 1
def zeitbisHeute(datumGeburt, datumHeute):
    while datumGeburt!=datumHeute:
        datum=(t,m,j)
    if monat in [1,3,5,7,8,10,12]:
       anzahl=31
    elif monat in [4,6,9,11]:
        anzahl=30
    elif schaltjahr(jahr):
        anzahl=29
    elif not schaltjahr(jahr):
        anzahl=28
    else:
        print "falsches datum"
    datumGeburt=i
    while datumGeburt(tag,monat,jahr)!=datumHeute(tag,monat,jahr):
        i=i+1
    return kanzahl

#Unterprogramm 2
def schaltjahr(jahr):
    return(jahr%400==0) or ((jahr%4==0) and not (jahr%100==0))
#Unterprogramm 3
def neuesDatum(datumGeburt, datumHeute):
      anzahl=0
      t=t+1
      if m<12:
          m=m+1
      elif m==12:
          t=1
          m=m+1
      else:
           t=1
           m=1
           j=j+1
      return halbzeit
#Hauptprogramm
print "das hier ist ein programm, um herauszufinden, wie lange es her ist, dass du halb so alt warst wie heute"
datumGeburt=input ("sag mir deinen geburtstag:")
(tag,monat,jahr)=datumGeburt
datumHeute=input ("sag mir das datum heute:")
(t,m,j)=datumHeute
kanzahl=zeitbisHeute(datumGeburt, datumHeute)
halbeanzahl=zeitbisHeute//2
halbzeit=neuesDatum(datumGeburt, datumHeute)
print (halbeanzahl)
print (halbzeit)
BITTE UM SCHNELLE HILFE

Re: keine Ausgabe???

Verfasst: Samstag 5. Mai 2012, 15:28
von BlackJack
@JuGa2000: Es werden sehr wohl die Fragen nach den Daten ausgegeben und die Antworten entgegen genommen. Und dann läuft Dein Programm in eine Endlosschleife. Das ist sowieso noch unglaublicher Unsinn, den Du da teilweise schreibst. Du denkst ganz offenbar nicht nach sondern schreibst da irgendwas hin und hoffst, dass es das macht was Du gerne hättest. Ohne Rücksicht darauf was es tatsächlich bedeutet was Du schreibst.

Den Fehler mit dem Aufrufen von Tupeln hast Du immer noch drin. Du greifst aus Funktionen auf Namen zu, die nicht als Argumente die Funktion betreten haben. Du hast Schleifen deren Schleifenkörper keinen Einfluss auf die Abbruchbedingung haben. Funktionsaufrufe werden mehrfach gemacht. Wenn falsche Eingabewerte erkannt werden, wird das ausgegeben — die Funktion läuft aber trotzdem weiter. Namen werden an Werte gebunden, und nie wieder verwendet. Dafür versuchst Du auf Namen zuzugreifen, die nie an Werte gebunden wurden. Funktionen bekommen Argumente die nie verwendet werden. Es wird versucht eine Funktion durch eine Zahl zu teilen. Das alles ist semantisch totaler Unsinn.

Du schreibst offenbar auch zu viel ungetestet. Denn viele von den Fehlern die ich beschreibe, hast Du sicher noch nie bemerkt, weil Dein Programm gar nicht erst so weit kommt. Man entwickelt ein Programm nicht, in dem man es erst komplett hin schreibt, und dann erst versucht es auszuführen, sondern Stück für Stück. Mindestens eine Funktion nach der anderen. Und man fängt keine neue Funktion an solange die bisherigen nicht funktionieren.

Man sollte keinen Code auf Modulebene stehen haben, der nicht dazu da ist Konstanten zu definieren. Das was nach Deinen Funktionen steht, sollte also auch in einer Funktion verschwinden. Üblicherweise nennt man die `main()` und ruft sie folgendermassen auf:

Code: Alles auswählen

def main():
    print 'blah...'
    # Code...

if __name__ == '__main__':
    main()
Dann kann man das Modul sowohl ausführen — dann wird die `main()`-Funktion aufgerufen — als auch als Modul importieren. Zum Beispiel in einer interaktiven Python-Shell um die Funktionen einzeln ausprobieren zu können.

Ausserdem kann man mit einer `main()`-Funktion nicht mehr aus Versehen oder aus Bequemlichkeit von anderen Funktionen auf Werte zugreifen, die nicht als Argumente an die Funktionen übergeben wurden.

Von der `input()`-Funktion sollte man in Python 2.x die Finger lassen. Da kann der Benutzer beliebige Python-Ausdrücke eingeben, die dann ausgewertet werden. Das ist eine Sicherheitslücke. Und man kann auch nur sehr schlecht auf Fehleingaben reagieren, weil man theoretisch mit *jeder* Ausnahme rechnen muss.

Re: keine Ausgabe???

Verfasst: Montag 7. Mai 2012, 06:42
von BlackJack
So könnte das aussehen, wenn man die Werkzeuge verwendet, die man in der Standardbibliothek findet:

Code: Alles auswählen

from datetime import date as Date


def main():
    print (
        'Dieses Programm berechnet wie lange es her ist, dass Du halb so alt\n'
        'warst wie heute.  Bitte gib Deinen Geburtstag in der Form YYYY-MM-DD\n'
        'ein:'
    ),
    try:
        year, month, day = map(int, raw_input().split('-'))
        birth_date = Date(year, month, day)
    except ValueError:
        print 'Falsches Datumsformat oder ungültige Werte!'
    else:
        half_age = (Date.today() - birth_date) / 2
        print 'Du warst vor %d Tagen am %s halb so alt wie jetzt.' % (
            half_age.days, birth_date + half_age
        )


if __name__ == '__main__':
    main()

Re: keine Ausgabe???

Verfasst: Montag 7. Mai 2012, 15:35
von nomnom
BlackJack hat geschrieben:So könnte das aussehen, wenn man die Werkzeuge verwendet, die man in der Standardbibliothek findet:

Code: Alles auswählen

...
year, month, day = map(int, raw_input().split('-'))
birth_date = Date(year, month, day)
...
Oder man nimmt ``strptime``:

Code: Alles auswählen

from datetime import datetime as Datetime
...
birth_date = Datetime.strptime(raw_input(), '%Y-%m-%d').date()
Das wirft auch einen ``ValueError`` bei einer fehlerhaften Eingabe … Ist aber vielleicht nicht so schön.

Re: keine Ausgabe???

Verfasst: Montag 7. Mai 2012, 16:13
von sma
Das ganze ist doch garantiert eine Programmier-Aufgabe, bei der es darum gehen soll, die Berechnung selbst anzustellen. Da ist es IMHO wenig hilfreich, mit Lösungen aus der Standard-Klassenbibliothek zu kommen. Es geht doch offenbar vielmehr darum, ein beliebiges Datum D1 in Tage T1 seit Datum D0 auszumultiplizieren, dann ein zweites Datum D2 zu nehmen, dazu T2 zu berechnen, dann T3 = (T2 - T1) / 2 + T1 zu berechnen und T3 wieder in ein Datum D3 zu verwandeln. Schaut man sich die Berechnung von T3 genauer an, kann man auch erkennen, dass (T1+T2)/2 eine Lösung ist.

Oder aber man nimmt den folgenden Ansatz. Sei D1 wieder das Geburtsdatum und D2 das heutige Datum. Dann kann ich T1 und T2 berechnen. Nun inkrementiere ich T1 um 1 und T1' um 2, bis T1' gleich T2 ist. Dann kann ich T1 wieder in ein Datum verwandeln und habe das gesuchte Ergebnis.

Und bei diesem Ansatz kann ich sogar noch anders vorgehen. Ich kann zu D auch direkt D' berechnen, ohne über T zu gehen. Dazu muss ich nur wissen, wie viele Tage jeder Monat hat.

Dies hier gibt z.B. den 26. 9. 2002 aus:

Code: Alles auswählen

def ist_schaltjahr(jahr):
    return bool(jahr % 400 or (jahr % 4 and not jahr % 100))

def tage_in_monat(monat, jahr):
    if monat == 2: return 28 + ist_schaltjahr(jahr)
    return 30 + bool(monat in (1, 3, 5, 7, 8, 10, 12))

def naechster_tag((tag, monat, jahr)):
    tage = tage_in_monat(monat, jahr)
    if tag < tage:
        return (tag + 1, monat, jahr)
    if monat < 12:
        return (1, monat + 1, jahr)
    return (1, 1, jahr + 1)

d_start = (13, 2, 1993)
d_ziel = (8, 5, 2012)

d = d_start
while d != d_ziel:
    d_start = naechster_tag(d_start)
    d = naechster_tag(naechster_tag(d))
print d_start
Stefan

PS: Das Programm enthält einen Denkfehler. Den zu entfernen überlasse ich dem Leser.

Re: keine Ausgabe???

Verfasst: Dienstag 8. Mai 2012, 12:16
von /me
sma hat geschrieben:Das ganze ist doch garantiert eine Programmier-Aufgabe, bei der es darum gehen soll, die Berechnung selbst anzustellen.
Dann erwarte ich aber auch eine faire Ansage der Form: "Ich soll für einen Kurs etwas programmieren. Ich habe allerdings im Unterricht nicht genug verstanden und bin auch nicht dazu gekommen es zu Hause nachzuarbeiten. Jetzt stehe ich da und brauche Hilfe und zwar unter folgenden Rahmenbedingungen."

Alleine die Verwendung von input tut ja bereits fast körperlich weh. Ich wüsste wirklich gerne, wer so etwas lehrt. Vielleicht liegt es ja hier einmal nicht am Schüler sondern am Lehrer/Buch.

Re: keine Ausgabe???

Verfasst: Dienstag 8. Mai 2012, 12:42
von BlackJack
@sma: Ich nehme mal an in `tage_in_monat()` meintest Du `int()` statt `bool()`, denn vom Typ `bool` ist das Ergebnis von ``in`` ja schon. :-P

Re: keine Ausgabe???

Verfasst: Dienstag 8. Mai 2012, 14:48
von nomnom
BlackJack hat geschrieben:@sma: Ich nehme mal an in `tage_in_monat()` meintest Du `int()` statt `bool()`, denn vom Typ `bool` ist das Ergebnis von ``in`` ja schon. :-P
Die Klammern sind nötig, und `bool` sowie `int` unnötig.

Code: Alles auswählen

>>> 3 + 4 in (1, 2, 3, 4)
False
>>> 3 + (4 in (1, 2, 3, 4))
4
>>> 

Re: keine Ausgabe???

Verfasst: Dienstag 8. Mai 2012, 14:57
von Hyperion
Ich hätte das wohl eher so formuliert:

Code: Alles auswählen

return 31 if monat in (1, 3, 5, 7, 8, 10, 12) else 30
@nomnom: Natürlich braucht man `int` nicht, aber es macht schon deutlich(er), was da genau passiert. Man kann natürlich `1 + True` schreiben, aber als wirklich lesbar empfinde ich so etwas nicht.