Soloway's recurring rainfall: Difference between revisions

m
m (→‎{{header|Raku}}: copy / pasto, add missing line, reformat slightly)
 
(29 intermediate revisions by 20 users not shown)
Line 1:
{{task}}
Soloway's Recurring Rainfall is commonly used to assesassess general programming knowledge by requiring basic program structure, input/output, and program exit procedure.
 
'''The problem:'''
 
Write a program that will read in integers and output their average. Stop reading when the value 99999 is input.
 
For languages that aren't traditionally interactive, the program can read in values as makes sense and stopping once 99999 is encountered. The classic rainfall problem comes from identifying success of Computer Science programs with their students, so the original problem statement is written above -- though it may not strictly apply to a given language in the modern era.
 
'''Implementation Details:'''
* Only Integers are to be accepted as input
* Output should be floating point
* Rainfall can be negative (https://www.geographyrealm.com/what-is-negative-rainfall/)
* For languages where the user is inputting data, the number of data inputs can be "infinite"
* A complete implementation should handle error cases reasonably (asking the user for more input, skipping the bad value when encountered, etc)
 
The purpose of this problem, as originally proposed in the 1980's through its continued use today, is to just show fundamentals of CS: iteration, branching, program structure, termination, management of data types, input/output (where applicable), etc with things like input validation or management of numerical limits being more "advanced". It isn't meant to literally be a rainfall calculator so implementations should strive to implement the solution clearly and simply.
 
'''References:'''
Line 67 ⟶ 78:
<syntaxhighlight lang="algol68">
BEGIN # read a sequence of integers, terminated by 99999 and outpout their average #
INT end value = 99999;
INT sum := 0;
INT count := 0;
BOOL invalid value := FALSE;
on value error( stand in, ( REF FILE f )BOOL: invalid value := TRUE );
WHILE
INT n := 0;
WHILE
STRING s;
print( ( "Enter rainfall (integer) or ", whole( end value, 0 ), " to quit: " ) );
read( ( sn, newline ) );
BOOL valid := UPB s >= LWB s; # invalid if the string is empty #value
FOR s pos FROM LWB s TO UPB s WHILE valid DO
IF valid := s[ s pos ] >= "0" AND s[ s pos ] <= "9"
THEN
n *:= 10 +:= ( ABS s[ s pos ] - ABS "0" )
FI
OD;
NOT valid
DO
print( ( "Invalid input, please enter an integer", newline ) );
invalid value := FALSE
OD;
n /= end value
Line 95 ⟶ 101:
END
</syntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">i: 0
sum: 0
 
while ø [
n: input "Enter rainfall as integer (99999 to quit): "
try? -> n: to :integer n
else [
print "Input must be an integer."
continue
]
if 99999 = n -> break
'i + 1
'sum + n
print ~« The current average rainfall is |sum // i|.
]</syntaxhighlight>
 
{{out}}
 
<pre>Enter rainfall as integer (99999 to quit): 145
The current average rainfall is 145.0.
Enter rainfall as integer (99999 to quit): 43678
The current average rainfall is 21911.5.
Enter rainfall as integer (99999 to quit): 9
The current average rainfall is 14610.66666666667.
Enter rainfall as integer (99999 to quit): 155
The current average rainfall is 10996.75.
Enter rainfall as integer (99999 to quit): 99999</pre>
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
<syntaxhighlight lang="qbasic"> 10 LET SUM = 0
20 FOR RAINFALL = 1 TO 1E38
30 INPUT "ENTER RAINFALL (AS AN INTEGER, OR 99999 TO QUIT): ";I
40 IF I = 99999 THEN END
50 IF I < > INT (I) THEN PRINT "?REENTER, MUST BE AN INTEGER": GOTO 30
60 LET SUM = SUM + I
70 PRINT " THE NEW AVERAGE RAINFALL IS "SUM / RAINFALL
80 NEXT RAINFALL</syntaxhighlight>
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
Line 346 ⟶ 391:
}
}
</syntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Although Delphi supports console applications that use simple keyboard input and teletype output, the primary focus of the language is GUI development. Consequently, I've produced a GUI version of the problem that uses the "TMemo" component to simulate a console interface.
 
To get the TMemo to behave like a console application, I've created an object that captures keyboard into to the TMemo and can return the keystrokes a chars, integers or reals. The object, which is called "TKeyWaiter," is simply created and attached to a TMemo component. While the object is alive, it will capture key stroke and return chars, integers or reals. It can be destroyed as soon as it is no longer needed. In fact, in this code, I create and destroy it for every input. The creation overhead is so low that there is no reason to create a global copy and keep it alive while the program is operating.
 
<syntaxhighlight lang="Delphi">
 
{This code would normally be in a library somewhere, but it is included here for clarity}
 
{TKeywaiter interface}
 
type TKeyWaiter = class(TObject)
private
FControl: TWinControl;
FControlCAbort: boolean;
protected
procedure HandleKeyPress(Sender: TObject; var Key: Char);
public
KeyChar: Char;
ValidKey: boolean;
AbortWait: boolean;
constructor Create(Control: TWinControl);
function WaitForKey: char;
function WaitForInteger: integer;
function WaitForReal: double;
property ControlCAbort: boolean read FControlCAbort write FControlCAbort;
end;
 
 
{ TMemoWaiter implementation }
 
type TControlHack = class(TWinControl) end;
 
constructor TKeyWaiter.Create(Control: TWinControl);
{Save the control we want to wait on}
begin
FControl:=Control;
FControlCAbort:=False;
end;
 
procedure TKeyWaiter.HandleKeyPress(Sender: TObject; var Key: Char);
{Handle captured key press}
begin
KeyChar:=Key;
ValidKey:=True;
if ControlCAbort then AbortWait:=KeyChar = #$03;
end;
 
 
function TKeyWaiter.WaitForKey: char;
{Capture keypress event and wait for key press control}
{Spends most of its time sleep and aborts if the user}
{sets the abort flag or the program terminates}
begin
ValidKey:=False;
AbortWait:=False;
TControlHack(FControl).OnKeyPress:=HandleKeyPress;
repeat
begin
Application.ProcessMessages;
Sleep(100);
end
until ValidKey or Application.Terminated or AbortWait;
Result:=KeyChar;
end;
 
 
function TKeyWaiter.WaitForInteger: integer;
var C: char;
var S: string;
begin
Result:=0;
S:='';
{Wait for first numeric characters}
repeat
begin
C:=WaitForKey;
if AbortWait or Application.Terminated then exit;
end
until C in ['+','-','0'..'9'];
{Read characters and convert to}
{integer until non-integer arrives}
repeat
begin
S:=S+C;
C:=WaitForKey;
if AbortWait or Application.Terminated then exit;
end
until not (C in ['+','-','0'..'9']);
Result:=StrToInt(S);
end;
 
 
type TCharSet = set of char;
 
function TKeyWaiter.WaitForReal: double;
var C: char;
var S: string;
const RealSet: TCharSet = ['-','+','.','0'..'9'];
begin
Result:=0;
S:='';
{Wait for first numeric characters}
repeat
begin
C:=WaitForKey;
if AbortWait or Application.Terminated then exit;
end
until C in RealSet;
{Read characters and convert to}
{integer until non-integer arrives}
repeat
begin
S:=S+C;
C:=WaitForKey;
if AbortWait or Application.Terminated then exit;
end
until not (C in RealSet);
Result:=StrToFloat(S);
end;
 
 
 
{===========================================================}
 
 
function WaitForReal(Memo: TMemo; Prompt: string): double;
{Wait for double entered into TMemo component}
var KW: TKeyWaiter;
begin
{Use custom object to wait for and capture reals}
KW:=TKeyWaiter.Create(Memo);
try
Memo.Lines.Add(Prompt);
Memo.SelStart:=Memo.SelStart-1;
Memo.SetFocus;
Result:=KW.WaitForReal;
finally KW.Free; end;
end;
 
var Count: integer;
var Average: double;
 
procedure RecurringRainfall(Memo: TMemo);
var D: double;
begin
Count:=0;
Average:=0;
while true do
begin
D:=WaitForReal(Memo,'Enter integer rainfall (99999 to quit): ');
if Application.Terminated then exit;
if (Trunc(D)<>D) or (D<0) then
begin
Memo.Lines.Add('Must be integer >=0');
continue;
end;
if D=99999 then break;
Inc(Count);
Average := Average + (1 / Count) * D - (1 / Count)*Average;
Memo.Lines.Add('New Average: '+FloatToStrF(Average,ffFixed,18,2));
end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
Enter integer rainfall (99999 to quit):
5.4
 
Must be integer >=0
Enter integer rainfall (99999 to quit):
-2
 
Must be integer >=0
Enter integer rainfall (99999 to quit):
5
 
New Average: 5.00
Enter integer rainfall (99999 to quit):
2
 
New Average: 3.50
Enter integer rainfall (99999 to quit):
10
 
New Average: 5.67
Enter integer rainfall (99999 to quit):
99999
 
 
Elapsed Time: 01:56.914 min
 
</pre>
 
=={{header|EasyLang}}==
{{trans|BASIC256}}
<syntaxhighlight>
repeat
print "Enter integral rainfall (99999 to quit): "
i = number input
until i = 99999
if error = 1 or i < 0 or i mod 1 <> 0
print "Must be an integer no less than 0, try again."
else
n += 1
sum += i
print " The current average rainfall is " & sum / n
.
.
</syntaxhighlight>
 
Line 428 ⟶ 687:
 
Specifically, we'll issue a prompt for every number requested, and reject lines which contain something that is not a number.
 
However, since we're supposedly collecting information about rainfall, and rainfall is not necessarily an integer, we'll allow arbitrary numbers here and trust the judgement of the person entering the numbers.
 
Implementation: <syntaxhighlight lang=J>require'general/misc/prompt'
Line 436 ⟶ 693:
list=. ''
while. do.
y=. (#~ >.=<.)_.".prompt'Enter rainfall int, 99999 to quit: '
if. 99999 e. y do. (+/%#)list return. end.
if. y-:y do. echo 'New average: ',":(+/%#)list=. list,y
Line 502 ⟶ 759:
}
}
</syntaxhighlight>
 
=={{header|jq}}==
The following program is mainly intended for interactive use.
An appropriate invocation would be: jq -nrR -f compute-averages.jq
Please note:
* a null response is regarded as an invalid entry;
* if there are no valid entries, the average is not printed;
* leading and trailing spaces in entries are ignored, and a single + or - prefix is allowed;
* an "end-of-file" condition is equivalent to the occurrence of 99999.
 
<syntaxhighlight lang=jq>
def isinteger: test("^ *[+-]?[0-9]+ *$");
 
def soloway:
label $out
| foreach (inputs, null) as $x (null;
.invalid = false
| if $x == null then .break = true
elif ($x|isinteger) then ($x|tonumber) as $n
| if $n == 99999
then .break = true
else .sum += $n | .n += 1
end
else .invalid = $x
end;
if .break then ., break $out
elif .invalid then .
else empty
end)
| (select(.invalid) | "Invalid entry (\(.invalid)). Please try again."),
(select(.break and .sum) | "Average is: \(.sum / .n)") ;
 
soloway
</syntaxhighlight>
 
=={{header|Julia}}==
Written for simplicity of reading rather than brevity. Changed from the originals to allow negative input, though I note that
allowing negative integer input and disallowing floating point seems strange given most "real-life" negative rainfall daily numbers are less than 1 inch.
<syntaxhighlight lang="julia">"""
Two annotated example outputs
Line 512 ⟶ 804:
the sentinel was the first and only input.
"""
function rainfall_problem(sentinel = 999999, allownegative = true)
total, entries = 0, 0
while true
print("Enter rainfall as $(allownegative ? "" : "nonnegative ")integer ($sentinel to exit): ")
n = tryparse(Int, readline())
if n == sentinel
break
elseif n == nothing || !allownegative && n < 0
println("Error: bad input. Try again\n")
else
Line 534 ⟶ 826:
rainfall_problem()
</syntaxhighlight>
 
=={{header|Nim}}==
We catch exceptions related to wrong input, i.e. non integer values. Negative values are allowed. If an end of file is encountered, the program terminates with an error message.
<syntaxhighlight lang="Nim">import std/[strformat, strutils]
 
const EndValue = 99999
 
 
var sum, count = 0.0
 
while true:
 
var value: int
 
# Read input until a valid integer if found.
var input: string
while true:
stdout.write &"Enter an integer value, {EndValue} to terminate: "
stdout.flushFile()
try:
input = stdin.readLine()
value = input.parseInt()
break
except ValueError:
echo &"Expected an integer: got “{input}”"
except EOFError:
quit "\nEncountered end of file. Exiting.", QuitFailure
 
# Process value.
if value == EndValue:
echo "End of processing."
break
count += 1
sum += value.toFloat
echo &" Current average is {sum / count}."
</syntaxhighlight>
 
{{out}}
Sample session.
<pre>Enter an integer value, 99999 to terminate: 10
Current average is 10.0.
Enter an integer value, 99999 to terminate: -20
Current average is -5.0.
Enter an integer value, 99999 to terminate: 50
Current average is 13.33333333333333.
Enter an integer value, 99999 to terminate: 3.5
Expected an integer: got “3.5”
Enter an integer value, 99999 to terminate: aaa
Expected an integer: got “aaa”
Enter an integer value, 99999 to terminate: 10
Current average is 12.5.
Enter an integer value, 99999 to terminate: 99999
End of processing.
</pre>
 
=={{header|Perl}}==
FWIW
<syntaxhighlight lang="perl" line>use strict;
use warnings;
 
use Scalar::Util qw(looks_like_number);
 
my ($periods, $accumulation, $rainfall);
 
sub so_far { printf "Average rainfall %.2f units over %d time periods.\n", ($accumulation / $periods) || 0, $periods }
 
while () {
while () {
print 'Integer units of rainfall in this time period? (999999 to finalize and exit)>: ';
$rainfall = <>;
last if looks_like_number($rainfall) and $rainfall and $rainfall == int $rainfall;
print "Invalid input, try again.\n";
}
(so_far, exit) if $rainfall == 999999;
$periods++;
$accumulation += $rainfall;
so_far;
}</syntaxhighlight>
{{out}}
<pre>Integer units of rainfall in this time period? (999999 to finalize and exit)>: raindrops
Invalid input, try again.
Integer units of rainfall in this time period? (999999 to finalize and exit)>: 2.00
Average rainfall 2.00 units over 1 time periods.
Integer units of rainfall in this time period? (999999 to finalize and exit)>: hail
Invalid input, try again.
Integer units of rainfall in this time period? (999999 to finalize and exit)>: 10**0
Invalid input, try again.
Integer units of rainfall in this time period? (999999 to finalize and exit)>: 1
Average rainfall 1.50 units over 2 time periods.
Integer units of rainfall in this time period? (999999 to finalize and exit)>:
Invalid input, try again.
Integer units of rainfall in this time period? (999999 to finalize and exit)>: 999999
Average rainfall 1.50 units over 2 time periods.</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">inputs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">5.4</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"five"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">99999</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">average</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_average</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" The current average rainfall is %g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">average</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">r</span> <span style="color: #008080;">in</span> <span style="color: #000000;">inputs</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Enter integral rainfall, 99999 to quit: %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">/*or r&lt;0*/</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- printf(1,"Must be a non-negative integer, try again.\n")</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Must be an integer, try again.\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">99999</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">average</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">-</span><span style="color: #000000;">average</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">n</span>
<span style="color: #000000;">show_average</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">show_average</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Enter integral rainfall, 99999 to quit: 5.4
Must be an integer, try again.
Enter integral rainfall, 99999 to quit: "five"
Must be an integer, try again.
Enter integral rainfall, 99999 to quit: 5
The current average rainfall is 5
Enter integral rainfall, 99999 to quit: -2
The current average rainfall is 1.5
Enter integral rainfall, 99999 to quit: 4
The current average rainfall is 2.33333
Enter integral rainfall, 99999 to quit: 10
The current average rainfall is 4.25
Enter integral rainfall, 99999 to quit: 99999
The current average rainfall is 4.25
</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="PureBasic">
Define.i n=0, sum=0
Define.f i
 
If OpenConsole()
Repeat
Print("Enter integral rainfall (99999 to quit): ")
i=ValF(Input())
If i=99999
Break
ElseIf i<0 Or i<>Int(i)
PrintN("Must be an integer no less than 0, try again.")
Else
n+1
sum+i
PrintN(" The current average rainfall is "+StrF(sum/n,5))
EndIf
ForEver
EndIf
</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|Python}}==
Line 562 ⟶ 1,012:
 
</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ $ "bigrat.qky" loadfile ] now!
[ 0 0
[ $ "Enter an integer (99999 to end): "
[ input $->n not iff
[ drop
$ " Try again: " ]
again ]
dup 99999 != while
+ dip 1+
again ]
drop
cr
over 0 = iff
[ 2drop
say "No data entered." ] done
say "Average: "
swap 10 point$ echo$ ] is srr ( --> )</syntaxhighlight>
 
{{out}}
 
As a dialogue in the Quackery shell.
 
<pre>/O> srr
...
Enter an integer (99999 to end): 99999
 
No data entered.
Stack empty.
 
/O> srr
...
Enter an integer (99999 to end): not an integer
Try again: 3.14159
Try again:
Try again: 2
Enter an integer (99999 to end): -3
Enter an integer (99999 to end): 5
Enter an integer (99999 to end): -7
Enter an integer (99999 to end): 11
Enter an integer (99999 to end): -13
Enter an integer (99999 to end): 17
Enter an integer (99999 to end): 99999
 
Average: 1.7142857143
Stack empty.</pre>
 
=={{header|Raku}}==
Line 567 ⟶ 1,066:
 
I notice that units are specified for neither measurement; time nor rainfall accumulation. Time is assumed to always increment in units of one, rainfall in some non-negative integer. "Integer" gets a little leeway in this entry. Floating point numbers or Rational numbers that are exactly equal to an Integer are allowed, even if they are technically not integers.
 
====After update to spec:====
Not going to bother to allow negative rainfall amounts. The "Negative rainfall" cited in the linked article references "total accumulated groundwater" '''NOT''' precipitation. Evaporation isn't rainfall. Much like dew or fog is not rainfall.
 
'''Further''', the linked reference article for Soloway's Recurring Rainfall <big>'''''SPECIFICALLY'''''</big> discusses marking an implementation as incorrect, or at least lacking, if it doesn't ignore and discard negative entries. You can't have it both ways.
 
<syntaxhighlight lang="raku" line># Write a program that will read in integers and
# output their average. Stop reading when the
Line 623 ⟶ 1,128:
Integer units of rainfall in this time period? (999999 to finalize and exit)>: 999999
Average rainfall 0.00 units over 0 time periods.</pre>
 
=={{header|RPL}}==
{{works with|HP|28}}
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
≪ "Enter rainfall, then ENTER" 1 DISP
"" "0123456789"
'''DO DO UNTIL''' KEY '''END'''
'''IF''' DUP2 POS '''THEN'''
ROT OVER + DUP 2 DISP ROT ROT
'''END'''
'''UNTIL''' "ENTER" == '''END'''
DROP STR→
≫ '<span style="color:blue">READB</span>' STO
≪ "Enter 9999 to end" 4 DISP
(0,0) 1 CF CLLCD
DO READB
'''IF''' DUP 9999 == '''THEN''' 1 SF
'''ELSE'''
1 R→C +
"Average = " OVER RE LAST IM / →STR +
3 DISP
'''END'''
'''UNTIL''' 1 FS? '''END'''
SWAP DROP CLMF
'''IFERR''' RE LAST IM / '''THEN''' DROP2 '''END'''
≫ '<span style="color:blue">RFALL</span>' STO
|
<span style="color:blue">READB</span> ''( → n )''
Initialize variables
Loop
if keystroke is an accepted char
add char to output and display it
until ENTER is pressed
clean stack and convert to integer
<span style="color:blue">RFALL</span> ''( → ) ''
initialize counters and flag, clear screen
loop
get rainfall
if break value then set flag
otherwise
accumulate rainfall and increment count
display average rainfall
until flag set
clean stack, unfreeze display
put average rainfall in stack if count ≠ 0
|}
 
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">QUIT = 99999
num = nil
count = 0
avg = 0.0
 
loop do
begin
print "Enter rainfall int, #{QUIT} to quit: "
input = gets
num = Integer(input)
rescue ArgumentError
puts "Invalid input #{input}"
redo
end
break if num == QUIT
count += 1
inv_count = 1.0/count
avg = avg + inv_count*num - inv_count*avg
end
 
puts "#{count} numbers entered, averaging #{average}"
</syntaxhighlight>
 
=={{header|Rust}}==
Line 657 ⟶ 1,243:
}
}
}
</syntaxhighlight>
=={{header|Swift}}==
<syntaxhighlight lang="swift">
import Foundation
 
var mean: Double = 0
var count: Int = 0
var prompt = "Enter integer rainfall or 99999 to exit:"
var term = " "
print(prompt, terminator: term)
while let input = readLine() {
defer {
print("count: \(count), mean: \(mean.formatted())\n\(prompt)", terminator: term)
}
guard let val = Int(input) else {
print("Integer values only")
continue
}
if val == 99999 {
(prompt, term) = ("Done","\n")
break
}
count += 1
mean += Double(val)/Double(count) - mean/Double(count)
}
</syntaxhighlight>
Line 662 ⟶ 1,273:
=={{header|Wren}}==
{{libheader|Wren-ioutil}}
<syntaxhighlight lang="ecmascriptwren">import "./ioutil" for Input
 
var n = 0
var sum = 0
while (true) {
var i = Input.integer("Enter integral rainfall (99999 to quit): ", 0)
if (i == 99999) break
n = n + 1
Line 678 ⟶ 1,289:
<pre>
Enter integral rainfall (99999 to quit): 5.4
Must be an integer no less than 0, try again.
Enter integral rainfall (99999 to quit): -2 five
Must be an integer no less than 0, try again.
Enter integral rainfall (99999 to quit): 5
The current average rainfall is 5
Enter integral rainfall (99999 to quit): -2
The current average rainfall is 31.5
Enter integral rainfall (99999 to quit): 4
The current average rainfall is 2.3333333333333
Enter integral rainfall (99999 to quit): 10
The current average rainfall is 54.666666666666725
Enter integral rainfall (99999 to quit): 99999
</pre>
 
=={{header|XPL0}}==
The problem is very simple except for the vague requirements for the user
interface and how to deal with unaccepted rainfall amounts.
<syntaxhighlight lang="XPL0">
real Rain, Sum, Count;
[Sum:= 0.; Count:= 0.;
loop [loop [Text(0, "Enter rainfall amount, or 99999 to quit: ");
Rain:= RlIn(0);
if Rain < 0. then
Text(0, "Must not be negative.^m^j")
else if Floor(Rain) # Rain then
Text(0, "Must be an integer.^m^j")
else quit;
];
if Rain = 99999. then quit;
Sum:= Sum + Rain;
Count:= Count + 1.;
Text(0, "Average rainfall is ");
RlOut(0, Sum/Count);
CrLf(0);
];
]</syntaxhighlight>
 
{{out}}
<pre>
Enter rainfall amount, or 99999 to quit: 5.4
Must be an integer.
Enter rainfall amount, or 99999 to quit: five
5
Average rainfall is 5.00000
Enter rainfall amount, or 99999 to quit: -2
Must not be negative.
Enter rainfall amount, or 99999 to quit: 4
Average rainfall is 4.50000
Enter rainfall amount, or 99999 to quit:
2.00000001
Must be an integer.
Enter rainfall amount, or 99999 to quit: .3e1
Average rainfall is 4.00000
Enter rainfall amount, or 99999 to quit: 99999
</pre>
1,983

edits