Recent

Author Topic: while loop with code before comparison  (Read 7682 times)

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
while loop with code before comparison
« on: August 11, 2020, 03:46:43 pm »
Suppose I want to display random numbers while they are less than some number. Such program can be written as:
Code: Pascal  [Select][+][-]
  1. var a: integer;
  2. begin
  3.   writeln('here are random percentages <= 75%');
  4.   randomize;
  5.   while true do
  6.   begin
  7.     a := random(101);
  8.     if a > 75 then break;
  9.     writeln(a, '%');
  10.   end;
  11. end.

This works, but I don't like the misleading "while true". The real condition is a <= 75. In C the solution to this is to used an assignment inside the condition, but I don't like it either.

So how about a language construct that would express that. For example:
Code: Pascal  [Select][+][-]
  1. var a: integer;
  2. begin
  3.   writeln('here are random percentages <= 75%');
  4.   randomize;
  5.   for a := random(101)
  6.   while a <= 75 do
  7.     writeln(a, '%');
  8. end.

This would work as well with blocks of code:
Code: Pascal  [Select][+][-]
  1. var a, min, max: integer;
  2. begin
  3.   writeln('here are random percentages <= 75%');
  4.   randomize;
  5.   for
  6.   begin
  7.     min := 0;
  8.     max := 100;
  9.     a := random(max-min+1) + min;
  10.   end
  11.   while a <= 75 do
  12.   begin
  13.     writeln('here is one such percentage:');
  14.     writeln(a, '%');
  15.   end;
  16. end.

Note: before anybody gets emotional about preserving the Pascal language, this is just a conversation, relax and enjoy.
Conscience is the debugger of the mind

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: while loop with code before comparison
« Reply #1 on: August 11, 2020, 04:10:50 pm »
Since the loop must go at least once and I don't mind endless loops I would use:
Code: Pascal  [Select][+][-]
  1.   writeln('here are random percentages <= 75%');
  2.   randomize;
  3.   repeat
  4.     a := random(101);
  5.     if a<=75
  6.       then writeln(a, '%')
  7.       else break;
  8.   until False;
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 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/

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: while loop with code before comparison
« Reply #2 on: August 11, 2020, 04:26:05 pm »
I don't see the need for either solution. One could just as well do:

Code: Pascal  [Select][+][-]
  1.   writeln('here are random percentages <= 75%');
  2.   randomize;
  3.   repeat
  4.     a := random(101);
  5.     if a <= 75 then writeln(a, '%');
  6.   until a > 75;

One might include, before the WriteLn the guard against a number being greater that 75 but other than that ... 8-)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: while loop with code before comparison
« Reply #3 on: August 11, 2020, 04:32:34 pm »
Code: Pascal  [Select][+][-]
  1.     var a: integer;
  2.     begin
  3.       writeln('here are random percentages <= 75%');
  4.       randomize;
  5.       a := random(101);
  6.       while a <= 75 do
  7.       begin
  8.         writeln(a, '%');
  9.         a := random(101);
  10.       end;
  11.     end.

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: while loop with code before comparison
« Reply #4 on: August 11, 2020, 07:40:27 pm »
Thanks for the suggestions.

Though for each of them, something is not quite satisfying to me:
- @Blaazen version includes an endless loop but it is not one
- @lucamar version includes twice the test
- @Martin_fr version includes a duplication of the assignment to a
Conscience is the debugger of the mind

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: while loop with code before comparison
« Reply #5 on: August 11, 2020, 07:47:44 pm »
Quote
- @Martin_fr version includes a duplication of the assignment to a

Code: Pascal  [Select][+][-]
  1. var a: integer = -1;
  2.     begin
  3.       writeln('here are random percentages <= 75%');
  4.       randomize;
  5.        while a <= 75 do
  6.       begin
  7.         writeln(a, '%');  // Ok, there will be the first not random = -1
  8.         a := random(101);
  9.       end;
  10.     end.

« Last Edit: August 11, 2020, 08:13:53 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: while loop with code before comparison
« Reply #6 on: August 11, 2020, 08:02:17 pm »
[…] So how about a language construct that would express that. […]
Can’t you just define your custom enumerator?
Code: Pascal  [Select][+][-]
  1. program randomNumbers(input, output, stdErr);
  2. {$mode objFPC}
  3.  
  4. type
  5.         randomNumber = type nativeInt;
  6.        
  7.         randomPercentageIterator = class
  8.                         private
  9.                                 threshold: randomNumber;
  10.                         public
  11.                                 // METHODS
  12.                                 procedure reset;
  13.                                 function getCurrent(): randomNumber;
  14.                                 function moveNext(): longBool;
  15.                                 // PROPERTIES
  16.                                 property current: randomNumber read getCurrent;
  17.                                 // CONSTRUCTORS/DESTRUCTORY
  18.                                 constructor create(const n: randomNumber);
  19.                                 destructor destroy; override;
  20.                 end;
  21.  
  22. procedure randomPercentageIterator.reset;
  23. begin
  24.         randomize;
  25. end;
  26.  
  27. function randomPercentageIterator.getCurrent(): randomNumber;
  28. begin
  29.         repeat
  30.                 getCurrent := random(101);
  31.         until getCurrent <= threshold;
  32. end;
  33.  
  34. function randomPercentageIterator.moveNext(): longBool;
  35. begin
  36.         moveNext := true;
  37. end;
  38.  
  39. constructor randomPercentageIterator.create(const n: randomNumber);
  40. begin
  41.         threshold := n;
  42.         reset;
  43. end;
  44.  
  45. destructor randomPercentageIterator.destroy;
  46. begin
  47.         inherited;
  48. end;
  49.  
  50. operator enumerator(const n: randomNumber): randomPercentageIterator;
  51. begin
  52.         result := randomPercentageIterator.create(n);
  53. end;
  54.  
  55. var
  56.         n: randomNumber;
  57. begin
  58.         for n in randomNumber(75) do
  59.         begin
  60.                 writeLn(n:3, ' %');
  61.         end;
  62. end.
« Last Edit: August 11, 2020, 08:07:29 pm by Kays »
Yours Sincerely
Kai Burghardt

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: while loop with code before comparison
« Reply #7 on: August 11, 2020, 08:14:29 pm »
Code: Pascal  [Select][+][-]
  1. function GetValue(var val: integer): boolean; inline;
  2. begin
  3.   val := random(101);
  4.   result := val <= 75; // the value is duplicated....
  5. end;
  6.  
  7. ......
  8.     var a: integer = 0;
  9.         begin
  10.           writeln('here are random percentages <= 75%');
  11.           randomize;
  12.            while GetValue(a) do
  13.               writeln(a, '%');
  14.         end.




eny

  • Hero Member
  • *****
  • Posts: 1634
Re: while loop with code before comparison
« Reply #8 on: August 11, 2020, 08:52:04 pm »
Two solutions that:
- do not require an endless loop;
- have only one test;
- only one assignment location of a random value.
But since this is a thread about opinion, I'm sure circular will have comments :D

Code: Pascal  [Select][+][-]
  1. program simple;
  2.  
  3. procedure Foo;
  4. label NotYet75;
  5. var a: integer;
  6. begin
  7.   Writeln('Foo');
  8. NotYet75:
  9.   a := random(101);
  10.   if a <= 75 then
  11.   begin
  12.     writeln(a,'%');
  13.     goto NotYet75;
  14.   end;
  15. end;
  16.  
  17. procedure Bar;
  18.  
  19.   function DoRandom(var n: integer): integer;
  20.   begin
  21.     n := random(101);
  22.     exit(n)
  23.   end;
  24.  
  25. var
  26.   a: integer;
  27. begin
  28.   writeln('Bar');
  29.   while DoRandom(a) <= 75 do
  30.     writeln(a, '%');
  31. end;
  32.  
  33. begin
  34.   Randomize;
  35.   Foo;
  36.   Bar;
  37.   readln;
  38. end.
  39.  
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: while loop with code before comparison
« Reply #9 on: August 11, 2020, 09:05:10 pm »
There are some clever solutions that were just proposed. We are getting somewhere  :)

- @Kays: defining a custom enumerator is satisfactory from a meaning point of view, but it is much stuff to write and I am a bit lazy
- @Fred vS: that's an elegant solution and I would probably choose to do that when that's possible, though it requires a value. What to do if the value is an interface? Maybe create a dummy interface that would pass the test.
- @Martin_fr: this solution seems to be actually the best, it works in all cases, no duplication of code. I would suggest an out parameter to avoid to have to initialize a.
Code: Pascal  [Select][+][-]
  1. function GetValue(out val: integer): boolean; inline;
  2. begin
  3.   val := random(101);
  4.   result := val <= 75; // test is defined here, that's no duplication
  5. end;
  6.  
  7. ......
  8.     var a: integer;
  9.     begin
  10.       writeln('here are random percentages <= 75%');
  11.       randomize;
  12.       while GetValue(a) do
  13.          writeln(a, '%');
  14.     end.
- @eny: haha the goto is a way to do something when the language structure is not available, so well not that satisfactory for me. The function that returns the value is clever, it works. There is some duplication of the value, but in this case I guess that would be ok.
« Last Edit: August 11, 2020, 09:12:46 pm by circular »
Conscience is the debugger of the mind

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: while loop with code before comparison
« Reply #10 on: August 11, 2020, 09:16:58 pm »
Quote
I would use an out parameter to avoid to have to initialize a.

Not sure to understand, does out parameter initialize the integer-value?
If yes, with what value?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: while loop with code before comparison
« Reply #11 on: August 11, 2020, 09:19:42 pm »
The out parameter does not care if the value has been initialized, because it will replace it. So you won't get any warning.
Conscience is the debugger of the mind

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: while loop with code before comparison
« Reply #12 on: August 11, 2020, 09:23:15 pm »
Yep, nice and with your solution the first loop is random too.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: while loop with code before comparison
« Reply #13 on: August 11, 2020, 09:30:56 pm »
Well that's essentially Martin_fr's solution.

So, yes, we have a satisfactory solution, using a function that either returns a boolean if the test passes, or that returns the generated value.

Still, the function can be far away if there is much code around, so I would still love a language construct for that.
Conscience is the debugger of the mind

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: while loop with code before comparison
« Reply #14 on: August 11, 2020, 09:33:30 pm »
Quote
so I would still love a language construct for that.

OK, everybody seems cool, open-mind and ready today.

What is your proposition?

 ;)
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018