357mag 2 Posted December 17 I'm working on a program using Logical Operators, and everything is working fine, except for one line that the compiler says it's incompatible types. It's a bit messy to look at also, but it works. And is there a way to tell Delphi to print the words true and false instead of the integer values -1 and 0? The line that is not correct yet is the fifth line down (the MemoResult lines) the one where I'm using the not operator. I don't know how best to write it. Here is my code: procedure TFormLogicalOperators.ButtonOKClick(Sender: TObject); var a: boolean; b: boolean; begin a := true; b := false; MemoResult.Text := ('a: ' + BoolToStr(a)) + sLineBreak; MemoResult.Text := MemoResult.Text + ('b: ' + BoolToStr(b)) + sLineBreak; MemoResult.Text := MemoResult.Text + ('a and b: ' + BoolToStr(a and b)) + sLineBreak; MemoResult.Text := MemoResult.Text + ('a or b: ' + BoolToStr(a or b)) + sLineBreak; MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not (a + b))) + sLineBreak; Share this post Link to post
Pat Foley 52 Posted December 17 I thought Remy mentioned using Add with a memo control. Here is a Sample using a nested procedure and a procedure with arguments that pass in controls that update the UI as needed. This sample uses both Format and ToString to help show the logic in the Controls as the program runs. implementation {$R *.dfm} const BooleanOperators: TArray<string> = ['And', 'or', 'xor','NotAnd','NotOr']; var A, B, RC: Boolean; procedure TForm13.Button1Click(Sender: TObject); begin A := True; B := True; // filter the controls props here use nil or '' if control or string not made yet demo357Repair(Memo1.Lines, Listbox1.Items, nil, A, B); end; { TForm13 } /// <summary> /// The TStrings of TMEMO are passed and requires a Memo1 and a Listbox1 to work /// /// </summary> procedure TForm13.Demo357Repair(const memoStrs, lbAItems, lbBItems : TStrings;var argA,argB: Boolean); // this flyover updates the value of RC each pass // how would you update A each time function flyoverCase(const Idx: NativeInt): Boolean; begin case Idx of 0: Result := argA and argB; 1: Result := argA or argB; 2: Result := argA xor argB; 3: Result := not argA or argB; // adjust these to suit your schema 4: Result := argA and not argB; else begin Result := False; memoStrs.Add('flyover needs attention');//surface errors end; end; // A := Result; // UX = User outputs memoStrs.Add( Format('%2s = %2s %s %2s', [RC.toString, argA.ToString(True), BooleanOperators[Idx], ArgB.ToString(False)]) ); lbAItems.Add(RC.ToString); //how would you connect lbBItems end; begin for var I := Low(BooleanOperators) to High(booleanOperators) do RC := flyoverCase(I); end; Share this post Link to post
Remy Lebeau 1435 Posted December 17 (edited) 11 hours ago, 357mag said: I'm working on a program using Logical Operators, and everything is working fine, except for one line that the compiler says it's incompatible types. Because they really are incompatible types. The '+' operator is not defined for Booleans. Read the documentation: https://docwiki.embarcadero.com/RADStudio/en/Expressions_(Delphi)#Operators So, you would have to convert the Booleans to Integer before using the '+' operator, then convert the result back to Boolean before using the 'not' operator, eg: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not Boolean(Ord(a) + Ord(b)))) + sLineBreak; Alternatively: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not ((Ord(a) + Ord(b)) <> 0))) + sLineBreak; On the other hand, your input expression does not match what your text says, which would be just this instead: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not a)) + sLineBreak; On a side note: you don't need all the extra parenthesis around your strings: MemoResult.Text := 'a: ' + BoolToStr(a) + sLineBreak; MemoResult.Text := MemoResult.Text + 'b: ' + BoolToStr(b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'a and b: ' + BoolToStr(a and b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'a or b: ' + BoolToStr(a or b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'not a: ' + BoolToStr(not a) + sLineBreak; 11 hours ago, 357mag said: And is there a way to tell Delphi to print the words true and false instead of the integer values -1 and 0? Yes. Read the documentation: https://docwiki.embarcadero.com/Libraries/en/System.SysUtils.BoolToStr There is an optional UseBoolStrs parameter that defaults to false. Simple set it to true instead. 4 hours ago, Pat Foley said: I thought Remy mentioned using Add with a memo control. Yes, I did, eg: MemoResult.Lines.Add('a: ' + BoolToStr(a)); MemoResult.Lines.Add('b: ' + BoolToStr(b)); MemoResult.Lines.Add('a and b: ' + BoolToStr(a and b)); MemoResult.Lines.Add('a or b: ' + BoolToStr(a or b)); MemoResult.Lines.Add('not a: ' + BoolToStr(not a)); Edited December 17 by Remy Lebeau Share this post Link to post
357mag 2 Posted December 17 (edited) You are way ahead of me. I have not studied functions or procedures yet. Can you write out the code? Edited December 17 by 357mag Share this post Link to post
Remy Lebeau 1435 Posted December 17 (edited) 22 minutes ago, 357mag said: You are way ahead of me. I have not studied functions or procedures yet. Can you write out the code? Really? You've shown enough code that demonstrates you know how to CALL functions. So, per the documentation, simply change BoolToStr(a) to BoolToStr(a, True), etc. Edited December 17 by Remy Lebeau Share this post Link to post
357mag 2 Posted December 17 (edited) Where do you place the function header? Calling a function that is already defined somewhere is one thing. Declaring or defining it is another. I may have to come back to this program later on. Edited December 17 by 357mag Share this post Link to post
Remy Lebeau 1435 Posted December 17 2 hours ago, 357mag said: Where do you place the function header? What are you talking about? There are no "function headers" in Delphi. 2 hours ago, 357mag said: Calling a function that is already defined somewhere is one thing. Declaring or defining it is another. I may have to come back to this program later on. Are you trying to reply to me or to Pat Foley? I'm so lost now were this discussion is going... Share this post Link to post
Die Holländer 49 Posted December 18 (edited) 10 hours ago, 357mag said: Where do you place the function header? Calling a function that is already defined somewhere is one thing. Declaring or defining it is another. I may have to come back to this program later on. In Delphi you just declare the unit where the functions you need are declared. For example Remy mentioned BoolToStr https://docwiki.embarcadero.com/Libraries/en/System.SysUtils.BoolToStr So, this function is in the System.SysUtils unit. In Delphi you can access that unit by declare it on top of your code: Uses System.SysUtils Now you can use the BoolToStr function in your code. Edited December 18 by Die Holländer Share this post Link to post