![]() |
Delphi-Version: 5
[Erledigt ]Logik-Problem mit and/or-Verknüpfung
Habe gerade einen Blackout.
Problem: Wenn Januar oder Februar im Schaltjahr vorliegt, soll eine Schaltjahreskorrektur vorgenommen werden (1), andernfalls 0. Wörtlich übersetzt:
Delphi-Quellcode:
Funktioniert so nicht.
//Logikfehler
{ if (monat=1) or (monat=2) and isleapyear(jahr) then schaltjahrkorrektur:=1 else schaltjahrkorrektur:=0; } Mit einer Hilfskrücke k Klappt es (Dirty Code).
Delphi-Quellcode:
Wie "denkt" der Compiler?
if (monat=1) or (monat=2) then k:=1 else k:=0;
if isleapyear(jahr) and (k=1) then schaltjahrkorrektur:=1 else schaltjahrkorrektur:=0; |
AW: Logik-Problem mit and/or-Verknüpfung
Hi,
auch wenn ich den Sinn der Sache nicht ganz verstehe, vermut ich dass der Fehler in der Klammerung besteht - and klammert stärker als or. Es steht also aktuell quasi das da:
Delphi-Quellcode:
aber du willst
if (monat=1) or ((monat=2) and isleapyear(jahr)) then
schaltjahrkorrektur:=1 else schaltjahrkorrektur:=0;
Delphi-Quellcode:
if ((monat=1) or (monat=2)) and isleapyear(jahr) then
schaltjahrkorrektur:=1 else schaltjahrkorrektur:=0; LG, Frederic |
AW: Logik-Problem mit and/or-Verknüpfung
Delphi-Quellcode:
Ich versuche sowas zu vermeiden, und mache es so
if (monat=1) or (monat=2) and isleapyear(jahr) then
Delphi-Quellcode:
Ist glaube ich verständlicher zu lesen.
if ((monat=1) or (monat=2)) and isleapyear(jahr) then
|
AW: Logik-Problem mit and/or-Verknüpfung
Sorry, auch mit deinen Klammern funktioniert es nicht.
LG Wolfgang |
AW: Logik-Problem mit and/or-Verknüpfung
@Popov und @fkerber
Ihr hattet recht, es ist ein Klammerproblem. Mit Popovs Klammern funzt es: Danke an Euch LG Wolfgang |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Nur der Vollständigkeit halber:
Delphi-Quellcode:
const
CORRECTIONVALUE: array[Boolean] of integer = (0, 1); ... schaltjahrkorrektur := CORRECTIONVALUE[(monat in (1,2)) and IsLeapYear(jahr)]; |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Danke Detlef,
in (1,2) hatte ich auch versucht, allerdings mit [] :( |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Du hast natürlich Recht, das kommt davon, wenn man direkt im Editor tippt. Vielleicht wäre das so aber lesbarer:
Delphi-Quellcode:
const
CORRECTIONVALUE: array[Boolean] of integer = (0, 1); POSSIBLYWRONGMONTHS = [MonthJanuary, MonthFebruary]; ... schaltjahrkorrektur := CORRECTIONVALUE[(monat in POSSIBLYWRONGMONTHS) and IsLeapYear(jahr)]; |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Hmm, sollte
Delphi-Quellcode:
nicht ausreichen?
Result:= ((Month in [1,2]) and IsLeapYear(Year))
Edit: also mein Delphi führt folgendes korrekt aus
Delphi-Quellcode:
function schaltjahrkorrektur(Month, Year: Integer): Boolean;
begin Result:= ((Month in [1,2]) and IsLeapYear(Year)); end; |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Wieso sollte es auch nicht, ich habe ja zugegebenermaßen einen Syntaxfehler gemacht. Die 2. Konstante habe ich nur eingeführt, um Magic Values zu vermeiden, man kann natürlich auch auf das Set verzichten und gleich die Konstanten nehmen, aber ich habe so etwas lieber zentral, falls man öfter darauf zugreift (DRY).
|
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Auch wenn ich deinen Code immer sehr schätze, muss ich zugeben das mich als Amateur deine Hilfsconstanten eher verwirren.
Aber das des funktioniert war eher darauf fokussiert Zitat:
|
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Nochmal wegen der Lesbarkeit und ohne Hilfskrücken
(unnötige Zusatzvariblen) habe ich es jetzt so und es funktioniert.
Delphi-Quellcode:
Zitat meines Lehrmeisters:
if (monat in[1,2]) and isleapyear(jahr) then
schaltjahrkorrektur:=1 else schaltjahrkorrektur:=0; "Geht nicht" gibt es nicht :-) LG Wolfgang |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Das waren aber weder Variablen noch Krücken, sondern einfache Konstanten.
|
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Sorry Detlef,
aber mein Code braucht jetzt weder zusätzliche Variablen, Konstanten noch externe Funktionen. Bin eigentlich mit dem jetzigen Code zufrieden :-) Mein k und Dein CORRECTIONVALUE sind also überflüssig LG Wolfgang |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
... und if / then brauchst du auch nimmer :roll: ROFL
Delphi-Quellcode:
schaltjahrkorrektur:= ((Month in [1,2]) and IsLeapYear(Year));
|
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Achtung, Klugscheißerkommentar!
Ist kompakter Code strebenswert oder lesbarer? Soll man das noch verstehen, wenn man in ein paar Jahren drüberschaut oder einfach übersehen, weil es ja so herrlich kompakt ist? Zunächst fällt auf, das Monate durch numerische Werte repräsentiert werden. Das ist ungünstig, denn für welchen Monat steht die 1? Immer für Januar? Was ist, wenn wir mit Fiskaljahren rechnen und der erste Monat des Fiskaljahres ist der Juli? Was bedeutet dann die 1? Ich würde daher den Monaten eine Enumerationsliste spendieren und den Monat durch seinen Namen repräsentieren. Dann ist das unmißverständlich. DeddyH ist schon auf dem richtigen Weg, indem er auf magische Konstanten verzichtet, aber stellt sich über seinen 'Correctionvalue' selbst ein Bein: Das macht den Ansatz dann wieder schwerer Lesbar. Wolfgang will doch nur den einfachen Satz ins delphianische übersetzt haben: "Wenn Januar oder Februar im Schaltjahr vorliegt, soll eine Schaltjahreskorrektur vorgenommen werden (1), andernfalls 0." In Englisch wäre das "A correctionvalue should be 1, if and only if the year is a leapyear and the month is a january and 0 otherwise". Fast am Ziel (Delphi kennt das so ja nicht)
Delphi-Quellcode:
Dieser Code liest sich fast so wie Wolfgangs Aufgabenstellung. Fast wortwörtlich, ergo verständlich.
If IsLeapYear() and month in [January, February] Then
CorrectionValue := 1 else CorrectionValue := 0; Wenn man nun die Eigenschaft 'Schaltjahr und Januar oder Februar' noch beschreiben möchte (z.B. weil das eine Bedingung ist, die Fred Rembremerdinger in seiner Gleichung aufgestellt hat) dann kann man das noch in eine Funktion auslagern und dieser Funktion einen aussagekräftigen Namen geben. Muss aber nicht. Das Einzige, was mich noch stören würde, ist der Name dieses Korrekturfaktors. Was korrigiert er? Wenn Wolfgang mehr Code zeigen würde, dann könnte man diesen Faktor noch umbenennen. Aber in dieser Aufgabenstellung reicht diese Bezeichnung aus. @Hobbyprogrammierer: Ist 1/0 gleichbedeutend mit einem Boolean |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Find Ich garnicht so klugscheißerisch... hört sich einfach nach Erfahrung an.
Hilfsvariablen oder "Krückenvariablen" heißen eigentlich ungünstig, weil sie Pflicht-Leseverbesserungs-Variablen heißen sollten und man davon soviele erstellen sollte, wie es für ein besseres Verständnis des Codes förderlich ist. Angenommen du berechnest in einer Funktion:
Delphi-Quellcode:
Wenn du jenes allerdings in komplexeren Methoden ohne weitere Bezeichner machst, wird der Code wieder ein Stückchen unübersichtlicher -> schwerer zu warten. Border := 10 * Parameter; Result := Border + Width; // Könntest du das auch ohne Border und in 1 Zeile abwickeln Result := (10 * Parameter) + Width Ich würde Klammern immer setzen, weil sie der Gleichnung verschiedene menschliche Interpretationsmöglichkeiten aberkennen, denn eigentlich ist das Problem, dass du scheinbar nicht genau weißt was passiert wenn sie nicht da sind: Dazu gibts einen kleinen Bereich in der Referenz: ![]() Zitat:
Delphi-Quellcode:
Nach unserem Styleguide würde die Bedingung zwanghaft nochmals eingeklammert werden aber das ist was hausinternes.If (IsLeapYear()) and (month in [January, February]) Then |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Es ist etwas OT, aber eine interessante Diskussion.
Ich persönlich verzichte gerne auf Überflüssiges im Code, wobei ich bei der Klammersetzung dazu tendiere, komplexe Ausdrücke durch Funktionen oder Hilfsvariablen verständlich zu machen. Ich persönlich finde es aber einen Overkill, einen Funktionsaufruf in Klammern zu setzen. Ich setze beim Leser meines Codes voraus, das er Delphi kann. Was allerdings grenzwertig wäre, wäre ein Konstrukt wie
Delphi-Quellcode:
.
if not ((a>=1) and (a<=10)) or not((b>=-2) and (b<=15)) then // habe ich Klammern vergessen?
Das ist zwar schön kompakt, aber man muss schon genauer hinschauen, um zu erkennen, das a und b auf 'außerhalb einer Toleranz' geprüft werden (also eigentlich ja negiertes 'innerhalb der Toleranz' :freak:). Also wieso nicht gleich
Delphi-Quellcode:
if Not InTolerance(a,1,10)) or not InTolerance(b,-2,15) then// garantiert keine Klammer vergessen
// oder nach Umformung (leichter zu lesen????) if Not (InTolerance(a,1,10)) and InTolerance(b,-2,15)) then |
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
Zitat:
|
AW: [Erledigt ]Logik-Problem mit and/or-Verknüpfung
:rofl: Aber da fehlt keine, das ist eine zu viel.
Herrlich ins Knie geschossen! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz