Recent

Author Topic: case of  (Read 9265 times)

flori

  • Full Member
  • ***
  • Posts: 183
case of
« on: March 04, 2021, 01:22:13 pm »
Hi everyone!
I have a small demo which categorize the contents of the leaf (such as apple, apricot leaf, etc)  ... low, medium high

Code: Pascal  [Select][+][-]
  1. Case Round(StringToNumber(edit6.Text)*100) of
  2.    2000..3000: N_res.text:='low';
  3.      End;
  4. case Round(StringToNumber(edit6.Text)*100) of
  5.    3001..4000: N_res.text:='medium';
  6.  End;
  7. if Nlab>40.01 then N_res.text:='high';


The categories (low, medium, high) unfortunately changes many times (every day:(). I put some Edit on the form where we can give  (we can specify) the values  (low: 20-30, medium: n1-n2, high<n)
Does anyone know how can I change code
Code: Pascal  [Select][+][-]
  1. 2000..3000: N_res.text:='low'
to calculate based on what I type (what values) into edit? (categorize based on what I type edits)
I attached demo
Thank you



Roland57

  • Full Member
  • ***
  • Posts: 152
Re: case of
« Reply #1 on: March 04, 2021, 01:31:10 pm »
Hello! I don't believe it be possible to use "case of" that way.

Maybe you could use the InRange function from the Math unit.

Regards.

Roland

MarkMLl

  • Hero Member
  • *****
  • Posts: 2414
Re: case of
« Reply #2 on: March 04, 2021, 02:13:23 pm »
I agree: the values have to be constant at compilation time.

OP: you've got extra ends in your example: should be something like

Code: Pascal  [Select][+][-]
  1.     Case Round(StringToNumber(edit6.Text)*100) of
  2.        2000..3000: N_res.text:='low';
  3.        3001..4000: N_res.text:='medium'
  4.     otherwise
  5.        if Nlab>40.01 then
  6.          N_res.text:='high'
  7.        else
  8.          N_res.text:='GOK'
  9.      End;
  10.  

MarkMLl
[/code]
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #3 on: March 04, 2021, 02:53:07 pm »
yes. But I would like to change: (see the picture)
instead of codes to read from Edit(s).

Zvoni

  • Hero Member
  • *****
  • Posts: 518
Re: case of
« Reply #4 on: March 04, 2021, 02:56:01 pm »
Not possible with Case Of
As Roland said: Use InRange from math
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #5 on: March 04, 2021, 02:56:32 pm »
ok I will try

Zvoni

  • Hero Member
  • *****
  • Posts: 518
Re: case of
« Reply #6 on: March 04, 2021, 03:04:57 pm »
quick and dirty (and not tested)
Code: Pascal  [Select][+][-]
  1. Var
  2.   iMin:Integer;
  3.   iMax:Integer;
  4. .
  5. .
  6. .
  7. iMin:=StringToNumber(editLeft.Text)*100;
  8. iMax:=StringToNumber(editRight.Text)*100;
  9.  
  10. If InRange(StringToNumber(edit6.Text)*100, iMin, iMAx) Then Do SomeThing;
  11.  
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #7 on: March 04, 2021, 03:41:19 pm »
Thanks. I tried your code
I modified :unfortunately it's not good either



Code: Pascal  [Select][+][-]
  1. function InRange ..
  2. var
  3.   iMin:real;
  4.   iMax:real;
  5. begin
  6. iMin:=StringToNumber(Edit1.Text);
  7. iMax:=StringToNumber(Edit2.Text);
  8.  
  9. If InRange (Round((StringToNumber(edit6.Text)*100)), iMin, iMAx) then
  10.    N_res.Text:='low' else N_res.Text:='error dose';  

end;


Kays

  • Sr. Member
  • ****
  • Posts: 299
  • Whasup!?
    • KaiBurghardt.de
Re: case of
« Reply #8 on: March 04, 2021, 03:50:55 pm »
I agree: the values have to be constant at compilation time.
Background information: The rationale is that the compiler must be able to verify that all case label values are disjunct, there is no overlap.

[…] Does anyone know how can I change code
Code: Pascal  [Select][+][-]
  1. 2000..3000: N_res.text:='low'
to calculate based on what I type (what values) into edit? (categorize based on what I type edits)[…]
You must “translate”, i.e. displace and scale your values to ranges you know at compile-time, something like:
Code: Pascal  [Select][+][-]
  1. uses
  2.         // for `sign`, but this is not /really/ necessary
  3.         math;
  4.  
  5. type
  6.         category = (low, medium, high);
  7.         categoryLimits = record
  8.                         // values including and above this threshold are `medium`
  9.                         lowMediumThreshold: integer;
  10.                         // values including and above this threshold are `high`
  11.                         mediumHighThreshold: integer;
  12.                 end;
  13.  
  14. function categorization(
  15.                 value: integer;
  16.                 const definition: categoryLimits
  17.         ): category;
  18. begin
  19.         with definition do
  20.         begin
  21.                 assert(lowMediumThreshold < mediumHighThreshold);
  22.                
  23.                 // normalize
  24.                 value := value - lowMediumThreshold;
  25.                 value := floor(value / (mediumHighThreshold - lowMediumThreshold));
  26.                 value := sign(value);
  27.         end;
  28.        
  29.         case value of
  30.                 -1:
  31.                 begin
  32.                         categorization := low;
  33.                 end;
  34.                 0:
  35.                 begin
  36.                         categorization := medium;
  37.                 end;
  38.                 1:
  39.                 begin
  40.                         categorization := high;
  41.                 end;
  42.                 otherwise
  43.                 begin
  44.                         assert(false);
  45.                 end;
  46.         end;
  47. end;
Then you can still use the case language construct.
Yours Sincerely
Kai Burghardt

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #9 on: March 04, 2021, 03:58:29 pm »
Kays: thanks the background info  :)

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #10 on: March 04, 2021, 05:00:38 pm »
unfortunately it does not work really with InRange (sure i don't use it well)?



glorfin

  • Full Member
  • ***
  • Posts: 127
  • LMath supporter
Re: case of
« Reply #11 on: March 04, 2021, 05:54:58 pm »
unfortunately it does not work really with InRange (sure i don't use it well)?
Yes, use of InRange implies use of if then else construct instead of case.
So, you have basically two choices: if then else instead of case, or map your values like Kay suggested. Personally I would use If Then Else with InRange.

GetMem

  • Hero Member
  • *****
  • Posts: 3986
Re: case of
« Reply #12 on: March 04, 2021, 05:57:58 pm »
@flori

You implemented your on version of InRange function which body is empty, remove it, then add math to the uses.  Instead of TEdit use TFloatSpinEdit, you can directly enter float values and set the Min/Max. Much easier this way.

flori

  • Full Member
  • ***
  • Posts: 183
Re: case of
« Reply #13 on: March 04, 2021, 06:09:41 pm »
Yes.
unfortunately for some reason it is miscategorized  (low dose)
is my code wrong?
 
Code: Pascal  [Select][+][-]
  1. var
  2. iMin:Double;
  3. iMax:Double;
  4.                  
  5. iMin:=StringToNumber(Edit1.Text);
  6. iMax:=StringToNumber(Edit2.Text);
  7.  
  8. If InRange (Round((StringToNumber(edit6.Text)*100)), iMin, iMAx) then
  9.    N_res.Text:='low' else N_res.Text:='error dose';
« Last Edit: March 04, 2021, 06:11:12 pm by flori »

WooBean

  • Full Member
  • ***
  • Posts: 111
Re: case of
« Reply #14 on: March 06, 2021, 11:36:02 am »
Just remark to "case" documentation - we can use ranges not limited to 0..255.

Below some code which I find a self explaining:
Code: Pascal  [Select][+][-]
  1. program project1;
  2. var i:integer;
  3.  
  4. begin
  5.   i:=1024;
  6.  
  7. {$R-} //needed to force compiling line below
  8.   writeln('Result of "',i,' in [1000..1025]" is ',i in [1000..1025]);
  9. //project1.lpr(9,63) Warning: range check error while evaluating constants (1025 must be between 0 and 255)
  10. //project1.lpr(9,57) Warning: range check error while evaluating constants (1000 must be between 0 and 255)
  11. {$R+} //now range checking is turned on
  12.   write('In case selector range value ',i);
  13.   case i of
  14.   1000..1025: writeln(' is between 1000..1025');
  15.   else
  16.     writeln(' is not between 1000..1025'); // never to happen
  17.   end;
  18.  
  19.   i:=1026;
  20.   write('In case selector range value ',i);
  21.   case i of
  22.   1000..1025: writeln(' is between 1000..1025');
  23.   else
  24.     writeln(' is not between 1000..1025'); // never to happen
  25.   end;
  26.  
  27.  
  28.   write('In case selector ranges value ',i);
  29.   case i of
  30.   1000..1025,1030..1032: writeln(' is among ranges 1000..1025,1030..1032');
  31.   else
  32.     writeln(' is not among ranges 1000..1025,1030..1032');
  33.   end;
  34.  
  35.   write('In case selector ranges value ',i);
  36.   case i of
  37.   1000..1005,1025..1032: writeln(' is among ranges 1000..1005,1025..1032');
  38.   else
  39.     writeln(' is not among ranges 1000..1005,1025..1032');
  40.   end;
  41.  
  42.   readln;
  43. end.
  44.  
  45.  
Win7/64, Lazarus 2.0.8 win64-win64, FPC 3.0.4

 

TinyPortal © 2005-2018