Lazarus

Programming => General => Topic started by: Dato39 on October 25, 2020, 08:58:15 pm

Title: Pascal
Post by: Dato39 on October 25, 2020, 08:58:15 pm
Recently I started my adventure with Pascal.  I need help, I have to write a program that gives 50% of the correct multiplication results and the rest of the cases a random result.
I'm counting on your help.  Greetings  ;)
Title: Re: Pascal
Post by: MarkMLl on October 25, 2020, 09:28:55 pm
How on Earth do you expect us to help if you don't show us your code?

Also it's usual to tell us what version of FPC/Lazarus you're running, what OS, and so on. There's plenty of FAQs around on how to ask questions in a way that's likely to get you a helpful answer (which, believe it or not, this is intended to be :-)

MarkMLl
Title: Re: Pascal
Post by: wildfire on October 25, 2020, 09:32:43 pm
Start by looking up randomize, random and looping structures.

That's the best information I can supply given the *very* limited specs. However doing it yourself will greatly help your learning experience.
Title: Re: Pascal
Post by: dbannon on October 26, 2020, 07:00:57 am
Err, just when is this assignment due in ?

Davo
Title: Re: Pascal
Post by: inko on October 26, 2020, 07:58:15 am
You might try copypasta the instructions of your assignment followed by the code you have tried so far and your questions about particular points of code, errors, or problems.
Title: Re: Pascal
Post by: 440bx on October 26, 2020, 06:59:38 pm
You might try copypasta ...
I'll contribute some spaghetti or lasagna to that effort.
Title: Re: Pascal
Post by: Paolo on October 26, 2020, 07:16:53 pm
Quote
I'll contribute some spaghetti or lasagna to that effort.
I would like to add also maccheroni and cannelloni  :D :D :D
Title: Re: Pascal
Post by: Thaddy on October 26, 2020, 08:14:01 pm
https://en.wikipedia.org/wiki/List_of_pasta is incomplete..... :P 8) :o :( ;D ;D
Title: Re: Pascal
Post by: winni on October 26, 2020, 09:02:14 pm
Hi!

What the most people outside Italy don't know:

Spaghettis are the interior of  maccheroni.

Winni
Title: Re: Pascal
Post by: Roland57 on October 26, 2020, 09:15:48 pm
Very interesting discussion and very good title.  :)
Title: Re: Pascal
Post by: Kays on October 26, 2020, 10:06:53 pm
Speaking of specs:
[…] the rest of the cases a random result. […]
Do you have to ensure the “random” result is not accidentally the correct result? I mean, there is a chance.
Title: Re: Pascal
Post by: Bart on October 26, 2020, 11:55:26 pm
I simply could not resist:
Code: Pascal  [Select][+][-]
  1. uses
  2.   SysUtils, Classes;
  3.  
  4. type
  5.  
  6.   { TPseudoRandomMultiplicator }
  7.  
  8.   TPseudoRandomMultiplicator = class
  9.   strict private
  10.     FFirstNumber: integer;
  11.     FSecondNumber: integer;
  12.     FIncorrectnessFraction: Double;
  13.     FIncorrectnessMargin: Integer;
  14.   private
  15.     function CalculateResult: Int64;
  16.     function GetOffset: Integer;
  17.     function GetFirstNumber: Integer;
  18.     function GetIncorrectnessFraction: Double;
  19.     function GetIncorrectnessMargin: Integer;
  20.     function GetMultiplicationResult: Int64;
  21.     function GetSecondNumber: Integer;
  22.     procedure SetFirstNumber(AValue: Integer);
  23.     procedure SetIncorrectnessFraction(AValue: Double);
  24.     procedure SetIncorrectnessMargin(AValue: Integer);
  25.     procedure SetSecondNumber(AValue: Integer);
  26.   public
  27.     constructor Create;
  28.     property FirstNumber: Integer read GetFirstNumber write SetFirstNumber;
  29.     property SecondNumber: Integer read GetSecondNumber write SetSecondNumber;
  30.     property IncorrectnessFraction: Double read GetIncorrectnessFraction write SetIncorrectnessFraction;
  31.     property IncorrectnessMargin: Integer read GetIncorrectnessMargin write SetIncorrectnessMargin;
  32.     property MultiplicationResult: Int64 read GetMultiplicationResult;
  33.   end;
  34.  
  35. { TPseudoRandomMultiplicator }
  36.  
  37. function TPseudoRandomMultiplicator.CalculateResult: Int64;
  38. begin
  39.   Result := Int64(FirstNumber) * Int64(SecondNumber);
  40.   if (Random < IncorrectnessFraction) then
  41.   begin
  42.     Result := Result + GetOffset;
  43.   end;
  44. end;
  45.  
  46. function TPseudoRandomMultiplicator.GetOffset: Integer;
  47. begin
  48.   Result := Random(IncorrectnessMargin) + 1;
  49.   if (Random < 0.5) then
  50.     Result := -Result;
  51. end;
  52.  
  53. function TPseudoRandomMultiplicator.GetFirstNumber: Integer;
  54. begin
  55.   Result := FFirstNumber;
  56. end;
  57.  
  58. function TPseudoRandomMultiplicator.GetIncorrectnessFraction: Double;
  59. begin
  60.   Result :=  FIncorrectnessFraction;
  61. end;
  62.  
  63. function TPseudoRandomMultiplicator.GetIncorrectnessMargin: Integer;
  64. begin
  65.   Result := FIncorrectnessMargin;
  66. end;
  67.  
  68. function TPseudoRandomMultiplicator.GetMultiplicationResult: Int64;
  69. begin
  70.   Result := CalculateResult;
  71. end;
  72.  
  73. function TPseudoRandomMultiplicator.GetSecondNumber: Integer;
  74. begin
  75.   Result := FSecondNumber;
  76. end;
  77.  
  78. procedure TPseudoRandomMultiplicator.SetFirstNumber(AValue: Integer);
  79. begin
  80.   if (FirstNumber <> AValue) then
  81.     FFirstNumber := AValue;
  82. end;
  83.  
  84. procedure TPseudoRandomMultiplicator.SetIncorrectnessFraction(AValue: Double);
  85. begin
  86.   if (IncorrectnessFraction <> AValue) then
  87.     IncorrectnessFraction := AValue;
  88. end;
  89.  
  90. procedure TPseudoRandomMultiplicator.SetIncorrectnessMargin(AValue: Integer);
  91. begin
  92.   if (IncorrectnessMargin <> AValue) then
  93.     FIncorrectnessMargin := AValue;
  94. end;
  95.  
  96. procedure TPseudoRandomMultiplicator.SetSecondNumber(AValue: Integer);
  97. begin
  98.   if (SecondNumber <> AValue) then
  99.     FSecondNumber := AValue;
  100. end;
  101.  
  102. constructor TPseudoRandomMultiplicator.Create;
  103. begin
  104.   FFirstNumber := 0;
  105.   FSecondNumber := 0;
  106.   FIncorrectnessFraction := 0.5;
  107.   FIncorrectnessMargin := 50;
  108. end;
  109.  
  110. var
  111.   PRM: TPseudoRandomMultiplicator;
  112.   N, Code: Integer;
  113.   S: String;
  114.  
  115. begin
  116.   Randomize;
  117.   repeat
  118.     PRM := TPseudoRandomMultiplicator.Create;
  119.     writeln('Enter a zero for both numbers to quit');
  120.     repeat
  121.       write('Enter first number: ');
  122.       readln(S);
  123.       Val(S, N, Code);
  124.       if (Code <> 0) then
  125.         writeln('Invalid number: "',S,'", please try again.');
  126.     until (Code = 0);
  127.     PRM.FirstNumber := N;
  128.     repeat
  129.       write('Enter second number: ');
  130.       readln(S);
  131.       Val(S, N, Code);
  132.       if (Code <> 0) then
  133.         writeln('Invalid number: "',S,'", please try again.');
  134.     until (Code = 0);
  135.     PRM.SecondNumber := N;
  136.     if (PRM.FirstNumber <> 0) and (PRM.SecondNumber <> 0) then
  137.     begin
  138.       writeln('Multiplying ',PRM.FirstNumber,' by ',PRM.SecondNumber,' gives ',PRM.MultiplicationResult);
  139.       writeln;
  140.     end;
  141.   until (PRM.FirstNumber = 0) and (PRM.SecondNumber = 0);
  142. end.

I'ld love to see him submit that  O:-)

Bart
Title: Re: Pascal
Post by: 440bx on October 27, 2020, 01:57:47 am
I'ld love to see him submit that  O:-)

Bart
He'd probably get a failing grade for having someone do his homework for him then, he blame you for it.  ;)
Title: Re: Pascal
Post by: Bart on October 27, 2020, 10:56:57 am
It needs a refinement, so that the error marging depends on the expected result.
If 6*3 gives you 52, it's to obvious the answer is wrong.
Also if the right answer is odd, the wrong answer should be odd as well.
And it might crash if you enter MaxInt for both values?

So, Dato39 still has lots of improvements to add, so he can claim it's his own code.

B.t.w. the code I posted is released under the LGPL 2.0 with linking exception (like Lazarus's LCL).
That means that Dato39 must publish his alterations if he submits his code  :)

Bart
Title: Re: Pascal
Post by: Bart on October 27, 2020, 11:45:40 am
Improved version.

Code: Pascal  [Select][+][-]
  1. {$Mode ObjFpc}
  2. {$H-} //no longstrings needed for this job
  3. uses
  4.   SysUtils, Classes;
  5.  
  6. type
  7.  
  8.   { TPseudoRandomMultiplicator }
  9.  
  10.   TPseudoRandomMultiplicator = class
  11.   strict private
  12.     FFirstNumber: integer;
  13.     FSecondNumber: integer;
  14.     FIncorrectnessFraction: Double;
  15.     FIncorrectnessMargin: Integer;
  16.   private
  17.     function CalculateResult: Int64;
  18.     function CheckAdditionOverflow(ALeft, ARight: Int64): Boolean;
  19.     function GetOffset(ARelativeTo: Int64): Integer;
  20.     function GetFirstNumber: Integer;
  21.     function GetIncorrectnessFraction: Double;
  22.     function GetIncorrectnessMargin: Integer;
  23.     function GetMultiplicationResult: Int64;
  24.     function GetSecondNumber: Integer;
  25.     procedure SetFirstNumber(AValue: Integer);
  26.     procedure SetIncorrectnessFraction(AValue: Double);
  27.     procedure SetIncorrectnessMargin(AValue: Integer);
  28.     procedure SetSecondNumber(AValue: Integer);
  29.   public
  30.     constructor Create;
  31.     property FirstNumber: Integer read GetFirstNumber write SetFirstNumber;
  32.     property SecondNumber: Integer read GetSecondNumber write SetSecondNumber;
  33.     property IncorrectnessFraction: Double read GetIncorrectnessFraction write SetIncorrectnessFraction;
  34.     property IncorrectnessMargin: Integer read GetIncorrectnessMargin write SetIncorrectnessMargin;
  35.     property MultiplicationResult: Int64 read GetMultiplicationResult;
  36.   end;
  37.  
  38. { TPseudoRandomMultiplicator }
  39.  
  40. function TPseudoRandomMultiplicator.CalculateResult: Int64;
  41. var
  42.   Offset: Integer;
  43.   TempResult: Int64;
  44. begin
  45.   Result := Int64(FirstNumber) * Int64(SecondNumber);
  46.   if (Random < IncorrectnessFraction) then
  47.   begin
  48.     Offset := GetOffset(Result);
  49.     if CheckAdditionOverflow(Result, Offset) then
  50.       Offset := -Offset;
  51.     TempResult := Result + Offset;
  52.     // sign should always be correct, so errors aren't that obvious
  53.     if ((TempResult < 0) and (Result > 0)) or
  54.        ((TempResult > 0) and (Result < 0)) then
  55.        TempResult := -TempResult;
  56.     // if none of the operands is zero, the answer cannot be zero
  57.     if (TempResult = 0) and (Result <> 0) then
  58.     begin
  59.       if (Result > 0) then
  60.       begin
  61.         repeat
  62.           Inc(TempResult)
  63.         until (TempResult <> Result);
  64.       end
  65.       else
  66.       begin
  67.         repeat
  68.           Dec(TempResult)
  69.         until (TempResult <> Result);
  70.       end;
  71.     end;
  72.     Result := TempResult;
  73.   end;
  74. end;
  75.  
  76. function TPseudoRandomMultiplicator.CheckAdditionOverflow(ALeft, ARight: Int64): Boolean;
  77. begin
  78.   if ((ALeft >= 0) and (ARight <= 0)) or
  79.      ((ALeft <= 0) and (ARight >= 0)) then
  80.      Result := False
  81.   else
  82.   begin
  83.     if (ALeft < 0) and (ARight < 0) then
  84.     begin
  85.       Result := (Low(Int64) - ALeft) >= ARight;
  86.     end
  87.     else
  88.     begin
  89.       Result := (High(Int64) - ALeft) >= ARight;
  90.     end;
  91.   end;
  92. end;
  93.  
  94. function TPseudoRandomMultiplicator.GetOffset(ARelativeTo: Int64): Integer;
  95. begin
  96.   if (Abs(ARelativeTo) > Abs(IncorrectnessMargin)) then
  97.     Result := Random(IncorrectnessMargin) + 1
  98.   else
  99.     Result := Random(3) + 1;
  100.   if (Odd(ARelativeTo) and not Odd(Result)) or
  101.      (Odd(Result) and not Odd(ARelativeTo)) then
  102.      Dec(Result);
  103.   if (Result = 0) then
  104.     Inc(Result, 2);
  105.   if (Random < 0.5) then
  106.     Result := -Result;
  107. end;
  108.  
  109. function TPseudoRandomMultiplicator.GetFirstNumber: Integer;
  110. begin
  111.   Result := FFirstNumber;
  112. end;
  113.  
  114. function TPseudoRandomMultiplicator.GetIncorrectnessFraction: Double;
  115. begin
  116.   Result :=  FIncorrectnessFraction;
  117. end;
  118.  
  119. function TPseudoRandomMultiplicator.GetIncorrectnessMargin: Integer;
  120. begin
  121.   Result := FIncorrectnessMargin;
  122. end;
  123.  
  124. function TPseudoRandomMultiplicator.GetMultiplicationResult: Int64;
  125. begin
  126.   Result := CalculateResult;
  127. end;
  128.  
  129. function TPseudoRandomMultiplicator.GetSecondNumber: Integer;
  130. begin
  131.   Result := FSecondNumber;
  132. end;
  133.  
  134. procedure TPseudoRandomMultiplicator.SetFirstNumber(AValue: Integer);
  135. begin
  136.   if (FirstNumber <> AValue) then
  137.     FFirstNumber := AValue;
  138. end;
  139.  
  140. procedure TPseudoRandomMultiplicator.SetIncorrectnessFraction(AValue: Double);
  141. begin
  142.   if (IncorrectnessFraction <> AValue) then
  143.     IncorrectnessFraction := AValue;
  144. end;
  145.  
  146. procedure TPseudoRandomMultiplicator.SetIncorrectnessMargin(AValue: Integer);
  147. begin
  148.   if (IncorrectnessMargin <> AValue) then
  149.     FIncorrectnessMargin := AValue;
  150. end;
  151.  
  152. procedure TPseudoRandomMultiplicator.SetSecondNumber(AValue: Integer);
  153. begin
  154.   if (SecondNumber <> AValue) then
  155.     FSecondNumber := AValue;
  156. end;
  157.  
  158. constructor TPseudoRandomMultiplicator.Create;
  159. begin
  160.   FFirstNumber := 0;
  161.   FSecondNumber := 0;
  162.   FIncorrectnessFraction := 0.5;
  163.   FIncorrectnessMargin := 50;
  164. end;
  165.  
  166.  
  167. function AskNumber(IsFirst: Boolean): Integer;
  168. const
  169.   FirstOrSecond: Array[Boolean] of String = ('second','first');
  170. var
  171.   S: String;
  172.   ErrorCode: Integer;
  173. begin
  174.   repeat
  175.     write('Enter ',FirstOrSecond[IsFirst],' number');
  176.     if IsFirst then
  177.       write (' ');
  178.     write(': ');
  179.     readln(S);
  180.     if (CompareText(S,'MaxInt') = 0) then
  181.     begin
  182.       Result := MaxInt;
  183.       ErrorCode := 0;
  184.     end
  185.     else
  186.     begin
  187.       if (CompareText(S,'LowInt') = 0) then
  188.       begin
  189.         Result := Low(Integer);
  190.         ErrorCode := 0;
  191.       end
  192.       else
  193.       begin
  194.       Val(S, Result, ErrorCode);
  195.       if (ErrorCode <> 0) then
  196.         writeln('Invalid number: "',S,'", please try again.');
  197.       end;
  198.     end;
  199.   until (ErrorCode = 0);
  200. end;
  201.  
  202. var
  203.   PseudoRandomMultiplicator: TPseudoRandomMultiplicator;
  204.  
  205. begin
  206.   Randomize;
  207.   repeat
  208.     try
  209.       PseudoRandomMultiplicator := TPseudoRandomMultiplicator.Create;
  210.       PseudoRandomMultiplicator.FirstNumber := AskNumber(True);
  211.       PseudoRandomMultiplicator.SecondNumber := AskNumber(False);
  212.       if (PseudoRandomMultiplicator.FirstNumber <> 0) and (PseudoRandomMultiplicator.SecondNumber <> 0) then
  213.       begin
  214.         try
  215.         writeln('Multiplying ',PseudoRandomMultiplicator.FirstNumber,' by ',PseudoRandomMultiplicator.SecondNumber,' gives ',PseudoRandomMultiplicator.MultiplicationResult);
  216.         except
  217.           on E: Exception do
  218.           begin
  219.             writeln('There was an error in the multiplication process:');
  220.             writeln(E.ClassName,': ',E.Message);
  221.           end;
  222.         end;
  223.         writeln;
  224.       end;
  225.     finally
  226.       PseudoRandomMultiplicator.Free;
  227.     end;
  228.   until (PseudoRandomMultiplicator.FirstNumber = 0) and (PseudoRandomMultiplicator.SecondNumber = 0);
  229.   writeln('Bye.');
  230. end.

Bart
Title: Re: Pascal
Post by: lucamar on October 27, 2020, 12:23:16 pm
All it rests now is to find some useful application for such a class  :D

Other than passing a grade, of course 8-)
Title: Re: Pascal
Post by: cdbc on October 27, 2020, 03:38:15 pm
Hi
@Bart: ...so you couldn't resist  ;D
Cool, good on you mate, me likey  ;)
I had a good laugh, thank you  ;)
Regards Benny
Title: Re: Pascal
Post by: Bart on October 27, 2020, 05:46:54 pm
All it rests now is to find some useful application for such a class  :D

Well, of course the applicaton should be able to set some properties (IncorrectnessFraction and IncorrectnessMargin) of that class.
So, it needs to handle options on the commandline.
Yet another excercise for TS (or me, if I'm bored).

Bart
Title: Re: Pascal
Post by: Bart on October 27, 2020, 06:35:35 pm
Yet another excercise for TS (or me, if I'm bored).

Seems I'm bored.
New and improved version:
Code: Pascal  [Select][+][-]
  1. {$Mode ObjFpc}
  2. {$H-} //no longstrings needed for this job
  3. uses
  4.   SysUtils, Classes;
  5.  
  6. type
  7.  
  8.   { TPseudoRandomMultiplicator }
  9.  
  10.   TPseudoRandomMultiplicator = class
  11.   strict private
  12.     FFirstNumber: integer;
  13.     FSecondNumber: integer;
  14.     FIncorrectnessFraction: Double;
  15.     FIncorrectnessMargin: Integer;
  16.   private
  17.     function CalculateResult: Int64;
  18.     function CheckAdditionOverflow(ALeft, ARight: Int64): Boolean;
  19.     function GetOffset(ARelativeTo: Int64): Integer;
  20.     function GetFirstNumber: Integer;
  21.     function GetIncorrectnessFraction: Double;
  22.     function GetIncorrectnessMargin: Integer;
  23.     function GetMultiplicationResult: Int64;
  24.     function GetSecondNumber: Integer;
  25.     procedure SetFirstNumber(AValue: Integer);
  26.     procedure SetIncorrectnessFraction(AValue: Double);
  27.     procedure SetIncorrectnessMargin(AValue: Integer);
  28.     procedure SetSecondNumber(AValue: Integer);
  29.   public
  30.     class function DefaultIncorrectnessFraction: Double;
  31.     class function DefaultIncorrectnessMargin: Integer;
  32.   public
  33.     constructor Create;
  34.     property FirstNumber: Integer read GetFirstNumber write SetFirstNumber;
  35.     property SecondNumber: Integer read GetSecondNumber write SetSecondNumber;
  36.     property IncorrectnessFraction: Double read GetIncorrectnessFraction write SetIncorrectnessFraction;
  37.     property IncorrectnessMargin: Integer read GetIncorrectnessMargin write SetIncorrectnessMargin;
  38.     property MultiplicationResult: Int64 read GetMultiplicationResult;
  39.   end;
  40.  
  41. { TPseudoRandomMultiplicator }
  42.  
  43. function TPseudoRandomMultiplicator.CalculateResult: Int64;
  44. var
  45.   Offset: Integer;
  46.   TempResult: Int64;
  47. begin
  48.   Result := Int64(FirstNumber) * Int64(SecondNumber);
  49.   if (Random < IncorrectnessFraction) then
  50.   begin
  51.     Offset := GetOffset(Result);
  52.     if CheckAdditionOverflow(Result, Offset) then
  53.       Offset := -Offset;
  54.     TempResult := Result + Offset;
  55.     // sign should always be correct, so errors aren't that obvious
  56.     if ((TempResult < 0) and (Result > 0)) or
  57.        ((TempResult > 0) and (Result < 0)) then
  58.        TempResult := -TempResult;
  59.     // if none of the operands is zero, the answer cannot be zero
  60.     if (TempResult = 0) and (Result <> 0) then
  61.     begin
  62.       if (Result > 0) then
  63.       begin
  64.         repeat
  65.           Inc(TempResult)
  66.         until (TempResult <> Result);
  67.       end
  68.       else
  69.       begin
  70.         repeat
  71.           Dec(TempResult)
  72.         until (TempResult <> Result);
  73.       end;
  74.     end;
  75.     Result := TempResult;
  76.   end;
  77. end;
  78.  
  79. function TPseudoRandomMultiplicator.CheckAdditionOverflow(ALeft, ARight: Int64): Boolean;
  80. begin
  81.   if ((ALeft >= 0) and (ARight <= 0)) or
  82.      ((ALeft <= 0) and (ARight >= 0)) then
  83.      Result := False
  84.   else
  85.   begin
  86.     if (ALeft < 0) and (ARight < 0) then
  87.     begin
  88.       Result := (Low(Int64) - ALeft) >= ARight;
  89.     end
  90.     else
  91.     begin
  92.       Result := (High(Int64) - ALeft) >= ARight;
  93.     end;
  94.   end;
  95. end;
  96.  
  97. function TPseudoRandomMultiplicator.GetOffset(ARelativeTo: Int64): Integer;
  98. begin
  99.   if (Abs(ARelativeTo) > Abs(IncorrectnessMargin)) then
  100.     Result := Random(IncorrectnessMargin) + 1
  101.   else
  102.     Result := Random(3) + 1;
  103.   if (Odd(ARelativeTo) and not Odd(Result)) or
  104.      (Odd(Result) and not Odd(ARelativeTo)) then
  105.      Dec(Result);
  106.   if (Result = 0) then
  107.     Inc(Result, 2);
  108.   if (Random < 0.5) then
  109.     Result := -Result;
  110. end;
  111.  
  112. function TPseudoRandomMultiplicator.GetFirstNumber: Integer;
  113. begin
  114.   Result := FFirstNumber;
  115. end;
  116.  
  117. function TPseudoRandomMultiplicator.GetIncorrectnessFraction: Double;
  118. begin
  119.   Result :=  FIncorrectnessFraction;
  120. end;
  121.  
  122. function TPseudoRandomMultiplicator.GetIncorrectnessMargin: Integer;
  123. begin
  124.   Result := FIncorrectnessMargin;
  125. end;
  126.  
  127. function TPseudoRandomMultiplicator.GetMultiplicationResult: Int64;
  128. begin
  129.   Result := CalculateResult;
  130. end;
  131.  
  132. function TPseudoRandomMultiplicator.GetSecondNumber: Integer;
  133. begin
  134.   Result := FSecondNumber;
  135. end;
  136.  
  137. procedure TPseudoRandomMultiplicator.SetFirstNumber(AValue: Integer);
  138. begin
  139.   if (FirstNumber <> AValue) then
  140.     FFirstNumber := AValue;
  141. end;
  142.  
  143. procedure TPseudoRandomMultiplicator.SetIncorrectnessFraction(AValue: Double);
  144. begin
  145.   AValue := Abs(AValue);
  146.   if (IncorrectnessFraction <> AValue) and (AValue < 1.0) then
  147.     FIncorrectnessFraction := AValue;
  148. end;
  149.  
  150. procedure TPseudoRandomMultiplicator.SetIncorrectnessMargin(AValue: Integer);
  151. begin
  152.   AValue := Abs(AValue);
  153.   if (IncorrectnessMargin <> AValue) and (AValue > 0) then
  154.     FIncorrectnessMargin := AValue;
  155. end;
  156.  
  157. procedure TPseudoRandomMultiplicator.SetSecondNumber(AValue: Integer);
  158. begin
  159.   if (SecondNumber <> AValue) then
  160.     FSecondNumber := AValue;
  161. end;
  162.  
  163. class function TPseudoRandomMultiplicator.DefaultIncorrectnessFraction: Double;
  164. begin
  165.   Result := 0.5;
  166. end;
  167.  
  168. class function TPseudoRandomMultiplicator.DefaultIncorrectnessMargin: Integer;
  169. begin
  170.   Result := 50;
  171. end;
  172.  
  173. constructor TPseudoRandomMultiplicator.Create;
  174. begin
  175.   FFirstNumber := 0;
  176.   FSecondNumber := 0;
  177.   FIncorrectnessFraction := 0.5;//DefaultIncorrectnessFraction;
  178.   FIncorrectnessMargin := 50;//DefaultIncorrectnessMargin;
  179. end;
  180.  
  181.  
  182. function AskNumber(IsFirst: Boolean): Integer;
  183. const
  184.   FirstOrSecond: Array[Boolean] of String = ('second','first');
  185. var
  186.   S: String;
  187.   ErrorCode: Integer;
  188. begin
  189.   repeat
  190.     write('Enter ',FirstOrSecond[IsFirst],' number');
  191.     if IsFirst then
  192.       write (' ');
  193.     write(': ');
  194.     readln(S);
  195.     if (CompareText(S,'MaxInt') = 0) then
  196.     begin
  197.       Result := MaxInt;
  198.       ErrorCode := 0;
  199.     end
  200.     else
  201.     begin
  202.       if (CompareText(S,'LowInt') = 0) then
  203.       begin
  204.         Result := Low(Integer);
  205.         ErrorCode := 0;
  206.       end
  207.       else
  208.       begin
  209.       Val(S, Result, ErrorCode);
  210.       if (ErrorCode <> 0) then
  211.         writeln('Invalid number: "',S,'", please try again.');
  212.       end;
  213.     end;
  214.   until (ErrorCode = 0);
  215. end;
  216.  
  217. const
  218.   FractionOpt = '--IncorrectnessFraction';
  219.   MarginOpt = '--IncorrectnessMargin';
  220.  
  221. procedure GetOptions(out AIncorrectnessFraction: Double; out AIncorrectnessMargin: Integer);
  222. var
  223.   ErrorCode, i: Integer;
  224.   S: String;
  225. begin
  226.   AIncorrectnessFraction :=  TPseudoRandomMultiplicator.DefaultIncorrectnessFraction;
  227.   AIncorrectnessMargin :=  TPseudoRandomMultiplicator.DefaultIncorrectnessMargin;
  228.   for i := 1 to ParamCount do
  229.   begin
  230.     if (Pos(UpperCase(FractionOpt)+'=', UpperCase(ParamStr(i))) = 1) then
  231.     begin
  232.       S := Copy(ParamStr(i), Length(FractionOpt)+2, MaxInt);
  233.       Val(S, AIncorrectnessFraction, ErrorCode);
  234.       if (ErrorCode = 0) then
  235.       begin
  236.         AIncorrectnessFraction := Abs(AIncorrectnessFraction);
  237.         if (AIncorrectnessFraction >= 1.0) then
  238.           AIncorrectnessFraction := TPseudoRandomMultiplicator.DefaultIncorrectnessFraction;
  239.       end
  240.       else
  241.         AIncorrectnessFraction := TPseudoRandomMultiplicator.DefaultIncorrectnessFraction;
  242.     end;
  243.     if (Pos(UpperCase(MarginOpt)+'=', UpperCase(ParamStr(i))) = 1) then
  244.     begin
  245.       S := Copy(ParamStr(i), Length(MarginOpt)+2, MaxInt);
  246.       Val(S, AIncorrectnessMargin, ErrorCode);
  247.       if (ErrorCode <> 0) then
  248.         AIncorrectnessMargin :=  TPseudoRandomMultiplicator.DefaultIncorrectnessMargin;
  249.     end;
  250.   end;
  251. end;
  252.  
  253. var
  254.   PseudoRandomMultiplicator: TPseudoRandomMultiplicator;
  255.   PreferredIncorrectnessFraction: Double;
  256.   PreferredIncorrectnessMargin: Integer;
  257.  
  258. begin
  259.   Randomize;
  260.   GetOptions(PreferredIncorrectnessFraction, PreferredIncorrectnessMargin);
  261.   repeat
  262.     try
  263.       PseudoRandomMultiplicator := TPseudoRandomMultiplicator.Create;
  264.       PseudoRandomMultiplicator.IncorrectnessFraction := PreferredIncorrectnessFraction;
  265.       PseudoRandomMultiplicator.IncorrectnessMargin := PreferredIncorrectnessMargin;
  266.       PseudoRandomMultiplicator.FirstNumber := AskNumber(True);
  267.       PseudoRandomMultiplicator.SecondNumber := AskNumber(False);
  268.       if (PseudoRandomMultiplicator.FirstNumber <> 0) and (PseudoRandomMultiplicator.SecondNumber <> 0) then
  269.       begin
  270.         try
  271.         writeln('Multiplying ',PseudoRandomMultiplicator.FirstNumber,' by ',PseudoRandomMultiplicator.SecondNumber,' gives ',PseudoRandomMultiplicator.MultiplicationResult);
  272.         except
  273.           on E: Exception do
  274.           begin
  275.             writeln('There was an error in the multiplication process:');
  276.             writeln(E.ClassName,': ',E.Message);
  277.           end;
  278.         end;
  279.         writeln;
  280.       end;
  281.     finally
  282.       PseudoRandomMultiplicator.Free;
  283.     end;
  284.   until (PseudoRandomMultiplicator.FirstNumber = 0) and (PseudoRandomMultiplicator.SecondNumber = 0);
  285.   writeln('Bye.');
  286. end.

Bart
Title: Re: Pascal
Post by: lucamar on October 27, 2020, 06:55:44 pm
I meant "usefull application" as in "doing something useful with it" or "some knowledge field where it might come in handy", not as in "some program that uses it". ;D
Title: Re: Pascal
Post by: Bart on October 27, 2020, 10:30:42 pm
I meant "usefull application" as in "doing something useful with it" or "some knowledge field where it might come in handy", not as in "some program that uses it". ;D

Of course, I got that.
It's just that I realized the program as such wasn't finisshed, so my next lines really were a reaction to the first part of that sentence: "All it rests now", meaning to state that "to find some useful application for such a class" wasn't the only thing left to do.
(Are you still with me?)

There are still things to do to make it more "enterprisy".
It definitively needs a factory and probably it needs an interface.
Also it's pedgree should be something like TObject->TCustomAbstractPseudoRandomMultiplicator->TCustomPseudoRandomMultiplicator->TPseudoRandomMultiplicator.
And logging is a must also then.

Finding a usecase for this class, might be kind of a challenge though  O:-)

Bart
TinyPortal © 2005-2018