Jump to content
357mag

One line of code not quite right

Recommended Posts

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

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
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 by Remy Lebeau

Share this post


Link to post

You are way ahead of me. I have not studied functions or procedures yet. Can you write out the code?

Edited by 357mag

Share this post


Link to post
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 by Remy Lebeau

Share this post


Link to post

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 by 357mag

Share this post


Link to post
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
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 by Die Holländer

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×