Recent

Author Topic: Sets - shorter expression  (Read 9236 times)

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Sets - shorter expression
« on: May 09, 2014, 05:48:53 pm »
Hello,

do I have any lack of Pascal languge? Is this possible to write in one line?
I mean some type-saving way to control one item of set with boolean.
Code: [Select]
type
  TOption = (oOne, oTwo, oThree);
  TOptions = set of Option;
...
if (Sender as TCheckBox).Checked
    then Options:=Options+[oThree]
    else Options:=Options-[oThree];     
Thanks.
Lazarus 2.1.0 r61214:62238 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Sets - shorter expression
« Reply #1 on: May 09, 2014, 06:20:10 pm »
Do you refer to the set operators? They are OK.

bigeno

  • Full Member
  • ***
  • Posts: 248
Re: Sets - shorter expression
« Reply #2 on: May 09, 2014, 06:25:12 pm »
Do you mean something in this way ?
Code: [Select]
  Options[oThree]:=(Sender as TCheckBox).Checked;
if yes, I think this is not possible.

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: Sets - shorter expression
« Reply #3 on: May 09, 2014, 06:33:07 pm »
personally I have an ever growing set of iif functions to use in such cases eg
Code: [Select]
function IIF(Check :Boolean; TrueResult, FalseResult :Integer):Integer;overload;inline;
function IIF(Check :Boolean; TrueResult, FalseResult :String):String;overload;inline;
....
implementation
function IIF(Check :Boolean; TrueResult, FalseResult :String):String;overload;inline;
begin
  If Check then Result := TrueResult else Result := FalseResult;
end;
......

but in this case I would do something like this.
Code: [Select]
function IIF(const Check :Boolean; const aSet:TOptions; const aOpt :TOption):TOptions;overload;inline;
begin
  Result := aSet;
  if Check then Include(Result, aOpt) else Exclude(Resut, aOpt)
end;
And its use looks like
Code: [Select]
Options := iif((Sender as TCheckBox).Checked,Options,oThree);
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: Sets - shorter expression
« Reply #4 on: May 09, 2014, 06:48:52 pm »
Thanks. In past I used function too, I named it SwitchOption instead of IIF. I hoped there exists some trick with set operators. It seems that Mr. Wirth omitted this.  :-[
Lazarus 2.1.0 r61214:62238 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1250
Re: Sets - shorter expression
« Reply #5 on: May 09, 2014, 07:00:22 pm »
I see no practical use for the following code, and would normally use your form of code, however - the challenge was raised :-) 
More set up time, but only one line of code.  In your case of course you would use (Sender as TCheckBox).Checked instead of bFlag...

Code: [Select]
Procedure TForm1.Button1Click(Sender: TObject);
Type
  TOption = (oOne, oTwo, oThree);
  TOptions = set of TOption;
Var
  Options: TOptions;
  bFlag: Boolean;
Const
  LU_Option: Array[Boolean] of TOptions = ([], [oThree]);
Begin
  Options := [oOne, oTwo, oThree];
  bFlag := False;

  Options := Options - [oThree] + LU_Option[bFlag];
End; 
LU is shorthand for Look Up
I don't think Mr Wirth did too bad :-)
« Last Edit: May 09, 2014, 07:06:44 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

bigeno

  • Full Member
  • ***
  • Posts: 248
Re: Sets - shorter expression
« Reply #6 on: May 09, 2014, 07:16:58 pm »
Nice  8)

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: Sets - shorter expression
« Reply #7 on: May 09, 2014, 07:42:25 pm »
I observed that other Pascal compiler (Delphi, GNU Pascal) cannot do it too. And it's not possible to hack it via Variant.
Lazarus 2.1.0 r61214:62238 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BeniBela

  • Hero Member
  • *****
  • Posts: 687
    • homepage
Re: Sets - shorter expression
« Reply #8 on: May 09, 2014, 11:57:04 pm »
Code: [Select]
PByte(@Options + ord(oThree) div 8)^ := (PByte(@Options + ord(oThree) div 8)^ or (1 shl ord(oThree))) and ((ord(bFlag)*$FF or not (1 shl ord(oThree)))) ;

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1250
Re: Sets - shorter expression
« Reply #9 on: May 10, 2014, 10:52:11 am »
:-)  Brilliant.  I've absolutely no clue how that code works, but at least you can easily change the option you're changing which is a distinct advantage over mine :-)
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5795
    • wiki
Re: Sets - shorter expression
« Reply #10 on: May 10, 2014, 12:41:17 pm »
Quote
Code: [Select]
PByte(@Options + ord(oThree) div 8)^

I am not sure this is endian save. So it may not work on all architectures.

eny

  • Hero Member
  • *****
  • Posts: 1588
Re: Sets - shorter expression
« Reply #11 on: May 10, 2014, 01:44:02 pm »
Code: [Select]
PByte(@Options + ord(oThree) div 8)^ := (PByte(@Options + ord(oThree) div 8)^ or (1 shl ord(oThree))) and ((ord(bFlag)*$FF or not (1 shl ord(oThree)))) ;
The person that writes this in code that I'm reviewing, gets fired  8)
All posts based on: Win10 (Win64); Lazarus 1.8.0 'stable' (#56594 win64) unless specified otherwise...

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1250
Re: Sets - shorter expression
« Reply #12 on: May 10, 2014, 02:36:25 pm »
Code: [Select]
PByte(@Options + ord(oThree) div 8)^ := (PByte(@Options + ord(oThree) div 8)^ or (1 shl ord(oThree))) and ((ord(bFlag)*$FF or not (1 shl ord(oThree)))) ;
The person that writes this in code that I'm reviewing, gets fired  8)
Ahh, but the point wasn't to produce reviewable code, but to get it onto one line.  Think of this as the obfuscated pascal competition.
(Sorry Blaazen, I appear to have hijacked your thread.  No disrepect was intended, just got excited by the challenge :) )
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

BeniBela

  • Hero Member
  • *****
  • Posts: 687
    • homepage
Re: Sets - shorter expression
« Reply #13 on: May 10, 2014, 02:48:47 pm »
The person that writes this in code that I'm reviewing, gets fired  8)

It is the multiplication, isn't it?

Far too inefficient for this task

Fixed it  8-)

Code: [Select]
PByte(@Options + ord(oThree) div 8)^ := (PByte(@Options + ord(oThree) div 8)^ or (1 shl ord(oThree))) and not (ord(not bFlag) shl ord(oThree)) ;
oh, crap, forgot the mod:

Code: [Select]
PByte(@Options + ord(oThree) div 8)^ := (PByte(@Options + ord(oThree) div 8)^ or (1 shl (ord(oThree) mod 8))) and not (ord(not bFlag) shl (ord(oThree) mod 8)) ;
« Last Edit: May 10, 2014, 02:58:37 pm by BeniBela »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5795
    • wiki
Re: Sets - shorter expression
« Reply #14 on: May 10, 2014, 03:12:22 pm »
1) If it was just about "on one line": Remove the line breaks, keep the original if.
Line breaks are for the human orly, so you can put the whole unit in one line, if you want.

2) from the OP:
Quote
I mean some type-saving way to control one item of set with boolean.

Probably meant "to save typing" rather than "save the type" (as in pascal being a strongly typed language).
But in either case: the whole PByte casting stuff, does not do either of that, or does it?

Quote
Code: [Select]
Options:=Options+[oThree]
If Options is a variable then using Include/Exclude may save a tiny bit of typing. But not much.

If you have lots of statements like that, all for the same type, write a helper function, or override an operator, or write a type helper.....