[Python]Bombers Fragetread

Ja, das bedeutet das, richtig. Aber dann hört die Schleife natürlich sofort auf, sobald die Bedingung nicht.mehr stimmt und das passiert, sobald entweder jahr==date[0] oder monat==date[1] oder tag==date[2]. Die Schleife soll aber erst aufhören, wenn das genaue Datum erreicht ist und nicht schon, wenn eine der drei Variablen übereinstimmt. Ich glaube du stehst gerade mächtig auf dem Schlauch.

Was passiert denn, wenn du als Geburtstag 7.4.1976 eingibst? Dann wäre 1976!=2012 und 7!=11 (heute), aber 4==4 und die Schleife ist beendet, bevor sie angefangen hat. Verstehst du jetzt deinen Fehler?
 
Zuletzt bearbeitet:
date[0], date[1] etc. ist auch ätzend. Importiere date aus datetime und verwende

Code:
today = date.today()
...
if (jahr != today.year || monat != today.month || tag != today.day)
    ...

Wenn Du dann noch Deine Variablen mit englischen Namen benennst, wird das Ganze zumindest leserlich :D
 
Troublegum schrieb:
Ja, das bedeutet das, richtig. Aber dann hört die Schleife natürlich sofort auf, sobald die Bedingung nicht.mehr stimmt und das passiert, sobald entweder jahr==date[0] oder monat==date[1] oder tag==date[2]. Die Schleife soll aber erst aufhören, wenn das genaue Datum erreicht ist und nicht schon, wenn eine der drei Variablen übereinstimmt. Ich glaube du stehst gerade mächtig auf dem Schlauch.

Was passiert denn, wenn du als Geburtstag 7.4.1976 eingibst? Dann wäre 1976!=2012 und 7!=11 (heute), aber 4==4 und die Schleife ist beendet, bevor sie angefangen hat. Verstehst du jetzt deinen Fehler?


Ja, ich verstehe was du meinst. Aber eigentlich sollte das "and" sowas doch verhindern. Es soll ja erst passieren, wenn wenn alle Bedingungen gleichzeitig erfüllt sind.
Ich glaub auch, irgendwie steh ich hier auf dem Schlauch... :(

Die Date.time Funktion habe ich erstmal rausgelassen, weil ich sie nicht so richtig verstanden habe, muss ich zugeben :eek: ... aber danke für das Beispiel :)
 
BomberDeluxe schrieb:
Ja, ich verstehe was du meinst. Aber eigentlich sollte das "and" sowas doch verhindern. Es soll ja erst passieren, wenn wenn alle Bedingungen gleichzeitig erfüllt sind.

Dann musst Du das auch so kodieren! Deine Schleife bricht bereits ab, wenn das Jahr übereinstimmt, weil Du auf Ungleichheit prüfst. Prädikatenlogik. Wenn die erste Bedingung nicht wahr ist, kann der gesamte Ausdruck nicht wahr sein.

Man könnte den Ausdruck wie gesagt mit dem Oder-Operator umschreiben, damit Deiner Intention Genüge getan ist. Aber die Lösung wie von @Troublegum vorgeschlagen sollte leichter zugänglich sein.
 
soares schrieb:
Dann musst Du das auch so kodieren! Deine Schleife bricht bereits ab, wenn das Jahr übereinstimmt, weil Du auf Ungleichheit prüfst. Prädikatenlogik. Wenn die erste Bedingung nicht wahr ist, kann der gesamte Ausdruck nicht wahr sein.

Hmm. Also pass auf, ich mach mal ein Beispiel.
Solange Hans kein rotes Hemd und kein weißes Hemd und kein schwarzes Hemd hat
kaufe ein Hemd
Nach diesem Prinzip hab ich mir das Vorgestellt.
Und mit dem Or Prinzip sähe das ja dann so aus:
Solange Hans kein rotes Hemd oder kein weißes Hemd oder kein schwarzes Hemd hat
kaufe ein Hemd
Das wäre ja dann irgendwie sinnlos, da die Schleife hier nur auftritt, wenn alles stimmt.

Ich steh wirklich auf dem Schlauch. Aber danke für eure Hilfe erstmal :daumen:
 
Du gehst da falsch heran. Geh die Kombinationen doch mal auf dem Papier durch:

Abbruchbedingung: Solange, bis aktuelles Datum erreicht. Das aktuelle Datum besteht aus Jahr, Monat und Tag, die alle drei übereinstimmen müssen. Sobald also Jahr == 2012 und Monat == 4 und Tag == 11 ist, soll abgebrochen werden.

Als simple Abbruchbedingung wäre also ein
Code:
curjahr = date[0];
curmonat = date[1];
curtag = date[2];
if( ejahr == curjahr && emonat == curmonat && etag == curtag )
  Abbrechen();
Da die Schleife aber so lange läuft, wie die Bedingung true ergibt, musst du obige Bedingung negieren - und zwar den gesamten Ausdruck! Hieße also
Code:
if( !(ejahr == curjahr && emonat == curmonat && etag == curtag) )
Negiert ergibt es folgende Bedingung:
Code:
if( ejahr != curjahr || emonat != curmonat || etag != curtag )

Du könntest es auch selbst debuggen:
Code:
bjahr = ejahr == curjahr;
bmonat = emonat == curmonat;
btag = etag == curtag;
Lass dir dann mal einzeln die Ergebnisse von den Variablen ausgeben. Sobald eines bei einer Und-Verknüpfung false ist, wird abgebrochen. Du willst aber, dass wenn alle false ergeben abgebrochen wird. Deswegen brauchst du obige Oder-Verknüpfung, weil die das Ergebnis der Und-Negation ist.

Steht aber eigentlich alles im Link von Troublegum drin.

Ein
Code:
if( ejahr != curjahr && emonat != curmonat && etag != curtag )
würde negiert
Code:
if( !(ejahr == curjahr || emonat == curmonat || etag == curtag) )
ergeben. Wie du denk ich mal selbst siehst, ist diese Bedingung fürn Arsch, weil abgebrochen wird, sobald das Jahr, Monat oder Tag eines Feldes des aktuellen Datums erreicht.

PS: Ich hab keine Ahnung von Python, hab also mal C-Syntax verwendet.
 
BomberDeluxe schrieb:
Nach diesem Prinzip hab ich mir das Vorgestellt.

"Solange Hans kein rotes Hemd und kein weißes Hemd und kein schwarzes Hemd hat
kaufe ein Hemd"

Dieser Gedanke ist durchaus richtig (auch wenn es nicht ganz zum Fall passt).

Formulieren wir es so um:

"Solange Hans kein rotes Hemd, keine schwarze Hose und keine braunen Schuhe trägt, probiere Kleider an."

Wenn Du das jetzt in Code übertragen willst, musst Du natürlich die dortige Semantik beachten. Die while-Schleife läuft so lange, wie der Schleifen-Ausdruck wahr ist. Du muss die Bedingungen also so formulieren, dass die Schleife erst dann abbricht, wenn Hans rotes Hemd, schwarze Hose und braune Schuhe trägt.

Wenn Du jetzt formulierst

while (hemd != rot and hose != schwarz and schuhe != braun)

ist der Schleifenausdruck nur dann wahr, wenn das Hemd NICHT rot und die Hose NICHT schwarz und die Schuhe NICHT braun sind. Also genau das Gegenteil von dem, was Du erreichen möchtest. Sobald Hans ein rotes Hemd anprobiert oder eine schwarze Hose oder braune Schuhe, kann der Ausdruck nicht wahr sein (und die Schleife bricht ab).


BomberDeluxe schrieb:
Und mit dem Or Prinzip sähe das ja dann so aus:

"Solange Hans kein rotes Hemd oder kein weißes Hemd oder kein schwarzes Hemd hat
kaufe ein Hemd"

Das wäre ja dann irgendwie sinnlos, da die Schleife hier nur auftritt, wenn alles stimmt.

Nein. Die Schleife läuft solange, wie mindestens eine der Bedingungen nicht erfüllt ist. Im Umkehrschluss: wenn alle Bedingungen erfüllt sind, bricht sie ab. Dein Beispiel ist schlecht gewählt, weil es bei Deinem Code-Problem drei verschiedene Kriterien sind, die geprüft werden sollen.

"Wenn Hans kein rotes Hemd oder keine schwarze Hose oder keine braunen Schuhe trägt, probiere Kleiner an."

Du musst Dir klar machen, wie das Programm abläuft. Zuerst wird die erste Bedingung geprüft. Ist diese erfüllt (Hans hat kein rotes Hemd an), gibt es eine neue Runde. Solange bis die Bedingung nicht mehr erfüllt ist (Hans hat ein rotes Hemd an). Erst dann wird die zweite Bedingung überhaupt geprüft! Und so geht das mit jeder Bedingung weiter. Bis er ein rotes Hemd, eine schwarze Hose und braune Schuhe trägt.
 
Oh mann... langsam begreif ich das... Die Schleife ist falsch, sobald einer der Komponenten erfüllt ist. Verstehe ich :)
Ach ja!!
Verstanden :-)
Vielen Dank!!! Ganz ehrlich, da wäre ich nie drauf gekommen...

Mal was ganz anders, kann ich in eine If Bedingung irgendwie schreiben, dass Variable x ein Vielfaches von 4 sein muss? Wegen dem Schaltjahr :)
 
Modulo gibt dir den Rest einer Division. Wenn der Null ist, ist die Zahl vollständig durch vier teilbar. Wenns einen Rest gibt, ist er nicht ganzzahlig durch vier teilbar (logisch).
Code:
if( jahr % 4 == 0 )
  // durch vier teilbar
else
  // nicht durch vier teilbar
 
Danke :)
und ich hab mich immer gefragt was Modulo überhaupt für einen Sinn hat :)
 
Hallo, da bin ich wieder.
nächste Frage:

Ich habe einen Ordner a. Dort sind mehrere Ordner drin. In jedem Ordner sind versch. Dateien. Jetzt will ich ein Programm schreiben, mit dem ich jeden Ordner im Hauptordner durchlaufe und alle dateien umbenenne. Ich möchte die 1. Datei "1" nennen, die 2. "2" und so weiter. Wenn jetzt alle Dateien im Unterordner umbenannt wurden, möchte ich im nächsten unterordner mit der nächsten Zahl weitermachen. So dass ich jeden Dateinamen nur 1 mal habe.

Ein Freund in der Schule meinte das gänge leicht mit einer Rekursion. Dann hat er ein kleines Programm geschrieben, aber ich habs nicht ganz verstanden und dann war die Pause schon rum ;-) .

Jetzt meine Frage: Wie könnte ich das machen? Ich hab ehrlich gesagt keine Ahnung... Vielleicht könnte ja jemand erklären, wie er vorgehen würde und ich versuch dann daraus das Programm zu entwickeln.
 
Was genau hast du denn nicht verstanden? Was Rekursion ist? Das bedeutet in erster Linie, dass eine Funktion/Methode sich (mehrfach) selbst aufruft, bis hoffentlich irgendwann (vor einem stack overflow) eine Abbruchbedingung erreicht wird. An dieser Stelle werden dann die Ergebnisse von ganz unten auf der "Leiter" immer weiter nach oben durchgereicht.

z.B.: Ordner gefunden, betreten, geschaut ob erstes Element darin wieder ein Ordner ist, wenn ja dann diesen wiederum betreten und das immer wieder so weiter.

Dazu findest du aber auch genug Info wenn du mal eine Runde suchst. Muss gar nicht Python-spezifisch sein. Fang aber vielleicht erst einmal mit einem leichteren Beispiel an, bis du das Prinzip verstanden hast. Das ist nämlich ganz anderes Denken, als der Ansatz mit Schleifen.
 
Also ich hab mir ein paar Tutorials angeschaut und sage und schreibe nicht besonders viel verstanden... Könntest du eventuell mal eine ganz einfache Rekursion posten? Wäre super :)
 
Code:
void c( int a )
{
  if( a > 0 )
    c( a - 1 );
  printf( "%d", a );
}
 
Es geht hier um Python!

Code:
def walk(level):
    if level > 10:
        return level

    return walk(level + 1)

print walk(0)
 
@ yuuri:
Also, ich probier mal:
angenommen

a=2
dann wird die funktion c ausgeführt, die a als Parameter besitzt.
Wenn a größer als 0 ist, wird die Funktion wieder ausgeführt, aber jetzt mit dem Parameter a-1.
Da a jetzt immer noch größer als 0 ist, wird die Funktion nochmal selber aufgerufen, allerdings ist a ja immernoch 2, da nirgendwo ein anderer Wert zugewiesen wird. Also geht die Funktion ins unendliche.

Das wahr jetzt sicher falsch oder?

@ soares: ich muss jetzt los, aber ich schaus mir nachher gleich an :)
 
soares schrieb:
Es geht hier um Python!
Für Rekursion bedarf es keinem Python, dafür kann ich auch Scheme oder Assembler nehmen wenn ich lustig bin! Geht in Brainfuck bestimmt auch...
BomberDeluxe schrieb:
a=2
dann wird die funktion c ausgeführt, die a als Parameter besitzt.
Wenn a größer als 0 ist, wird die Funktion wieder ausgeführt, aber jetzt mit dem Parameter a-1.
Da a jetzt immer noch größer als 0 ist, wird die Funktion nochmal selber aufgerufen, allerdings ist a ja immernoch 2, da nirgendwo ein anderer Wert zugewiesen wird. Also geht die Funktion ins unendliche.

Das wahr jetzt sicher falsch oder?
Ja.
Code:
c( 2 )     a = 2
           a > 0 -> c( 2 - 1 );      printf( 2 );
 |
 v                                         ^
c( 1 )     a = 1                           |
           a > 0 -> c( 1 - 1 );      printf( 1 );
 |
 v                                         ^
c( 0 )     a = 0                           |
           a == 0 -----------------> printf( 0 );
Bei a < 1 wird c nicht mehr aufgerufen. Du kommst also nie ins unendliche. Stattdessen wird die Funktion heraufgegangen und er gibt alle Zahlen von 0 bis a aus.
 
Zuletzt bearbeitet:
@yuuri: Ok, ich wusste nicht, dass a immer neu zugewiesen wird.
Ist a hier eigentlich eine globale Variable, weil sie ja zum ersten mal außerhalb der Funktion definiert werden muss?
Warum wird printf immer ausgeführt? Eigentlich müsste es doch nur am Ende ausgegeben werden, weil vorher ja immer gleich die Funktion wieder von vorn aufgerufen wird, und sie so gar nicht zum ende kommt.

Zu Soares:
Code:
def walk(level):
    if level > 10:
        return level
 
    return walk(level + 1)
 
print walk(0)

Was genau macht das return? Lässt es einfach die Funktion/Variable/usw. nochmal ausführen?

Auch hier die gleichen Fragen wie oben:
Ist level eine globale Variable?
Warum wird print immer ausgeführt? Es normalerweise dürfte es ja nur am Ende ausgeführt werden, weil durch das return die Funktion immer von neuem beginnt, bis der print befehl bearbeitet werden kann.
 
Pass auf: Der Python-Code von soares macht nicht das gleiche wie der Code von Yuuri.

'level' ist keine globale Variable, 'print' wird nur einmal am Ende ausgeführt und in Zeile 5 wird 'walk' natürlich vor 'return' aufgerufen. Das ist ja der Witz an der ganzen Sache.

Am Ende wird bei dem Code aber einfach immer nur 11 ausgegeben.
 
Zurück
Oben