This program is a hydrology toolkit that offers three computational modules via a menu: rainfall distribution (“RAIN D”), flood hydrograph generation (“Fld Hyd”), and storage/discharge function rates (“FUNC RATES”). The menu dispatches to subroutines using the computed GO TO at line 395 (`GO TO Number*10`), where the user enters 40, 45, or 55 to jump to lines 400, 450, or 550 respectively. The flood hydrograph section implements a unit hydrograph convolution, multiplying rainfall excess values against unit graph ordinates and summing them to produce a flow time series. The program embeds all its test data in DATA statements and uses DIM arrays for intermediate storage, with the storage-routing section computing S+Q/2 and S-Q/2 routing function values scaled by acre-feet conversion factors (43560 sq ft per acre, 10800-second time steps).
Program Analysis
Program Structure
The program is organised as a menu dispatcher plus three self-contained computational modules, each terminated by a GO TO 372 (or GO TO 370) to return to the menu. The overall flow is:
- Lines 350–395: Title, menu display, and computed branch (
GO TO Number*10) - Lines 400–430: Module 1 — Rainfall Distribution (“RAIN D”)
- Lines 450–525: Module 2 — Flood Hydrograph (“Fld Hyd”)
- Lines 550–595: Module 3 — Storage/Routing Function Rates (“FUNC RATES”)
- Line 1000:
STOP(reached when user enters 100)
Computed GO TO Dispatch
Line 395 uses GO TO Number*10 to branch: entering 40 jumps to line 400, 45 to line 450, 55 to line 550, and 100 to line 1000. This is a compact menu-dispatch idiom that avoids a chain of IF statements. No bounds checking is performed, so any other input will cause an error due to jumping to a non-existent line.
Module 1 — Rainfall Distribution (Lines 400–430)
Reads a count N, total rainfall R, and two label strings from DATA, then reads N fractional distribution values into array F. For each period it computes E(I) = R * F(I) (rainfall excess per period) and prints a table of time period, fraction, and excess depth. The DATA at lines 417–418 encodes a 6-period, 6.00-inch, 100-year event for “Luther Lake”.
Module 2 — Flood Hydrograph (Lines 450–525)
Implements a discrete unit hydrograph convolution to generate a flood hydrograph from rainfall excess and unit graph ordinates. The convolution loop runs from J=1 to NQ = NP + NUHGQ - 1, the expected length of the output hydrograph. A conditional at line 478 splits the inner loop into two cases depending on whether J ≤ NUHGQ or not.
There is a significant bug in the convolution logic: inside the first branch (lines 479–483), Q(J) is overwritten on each iteration of the inner I loop rather than accumulating. The correct formulation would add P(K)*U(I) to a running sum rather than assigning it to Q(J) and then adding Q(J). As a result SUMF does not correctly accumulate the convolution sum. The same error appears in the parallel dead-code section at lines 492–505.
Lines 492–505 are entirely unreachable dead code: line 491 unconditionally branches to line 506, so lines 492–505 can never execute. These appear to be remnants of an earlier version of the algorithm that was not fully removed.
Module 3 — Storage Routing Function Rates (Lines 550–595)
Computes the storage-routing working curves S/TR, S/TR − Q/2, and S/TR + Q/2 for reservoir routing using Muskingum or level-pool methods. Storage S(I) is built up cumulatively from trapezoidal area integration scaled by the elevation increment ELEVD. The conversion at line 563 applies the factor 43560/10800 (square feet per acre divided by seconds per time-step) to convert acre-feet storage to a compatible flow unit.
Line 565 uses LET B(I) = INT NUM/10 to round B(I) to one decimal place via an intermediate variable NUM = B(I)*10, a common BASIC rounding idiom since INT only truncates toward zero.
Notable Anomalies and Bugs
- Convolution overwrite bug (line 481, 488, 495, 503):
Q(J) = P(K)*U(I)should accumulate (i.e.LET Q(J) = Q(J) + P(K)*U(I)); the current assignment discards previous iterations, makingSUMFincorrect. - Dead code (lines 492–505): Unconditional
GO TO 506at line 491 makes these lines permanently unreachable. - Operator precedence at line 565:
INT NUM/10is parsed as(INT NUM)/10in Sinclair BASIC, which is the intended behaviour here, but could be misleading to a reader expectingINT(NUM/10). - Module 2 DATA misalignment:
READ NUHGQ,TR,NPat line 458 expects the unit graph to have 12 ordinates and 12 rainfall excesses, but lines 512–515 supply only 12 unit graph values split across two DATA lines and 12 rainfall values split across two more — the counts match but the split across lines is worth noting for maintainability. - REM at line 1: The author acknowledges bugs directly in the source:
REM This program has "bug problems"--doesn't run completely.
Variable Summary
| Variable | Module | Purpose |
|---|---|---|
Number | Menu | User menu selection (40/45/55/100) |
N, R, T$, Y$ | RAIN D | Period count, total rainfall, title strings |
F(24), E(24) | RAIN D | Fractional distribution and excess depth arrays |
NUHGQ, TR, NP | Fld Hyd | Unit graph ordinate count, time interval, rainfall period count |
U(15), P(15), Q(30) | Fld Hyd | Unit graph ordinates, rainfall excesses, convolution output |
SUMF, IHR, NQ | Fld Hyd | Accumulated flow, current hour, total output periods |
H(10), A(10), Q(10) | FUNC RATES | Head, area, and discharge arrays |
S(10), B(10), C(10), D(10) | FUNC RATES | Storage, S/TR, S/TR−Q/2, S/TR+Q/2 arrays |
ELEVD, SUM, NUM | FUNC RATES | Elevation increment, cumulative storage, rounding intermediate |
Content
Source Code
1 REM This program has "bug problems"--doesn't run completely
350 REM "hydrology2"
360 PRINT AT 1,7;"Hydology #2"
365 PRINT
370 PRINT AT 3,4;"Menu Selection"
371 PRINT
372 PRINT "Input a 40 for RAIN D, Input a 45 for Fld Hyd, Input a 55 for FUNC RATES Input a 100 if you are finished."
373 PRINT
385 INPUT Number
390 CLS
395 GO TO Number*10
400 REM "RAIN D"
401 PRINT "PROGRAM DISTRIBUTES TOTAL RAINFALL OR RAINFALL EXCESS (R) FOR N PERIODS "
402 DIM F(24): DIM E(24)
403 READ N,R,T$,Y$
404 FOR I=1 TO N
405 READ F(I)
406 NEXT I
407 PRINT TAB 10;T$
408 PRINT
409 PRINT TAB 5;Y$;TAB 10;R;" IN. EXCESS"
410 PRINT
411 PRINT TAB 2;"TIME";TAB 12;"%";TAB 18;"RAIN"
412 PRINT
413 FOR I=1 TO N
414 LET E(I)=R*F(I)
415 PRINT TAB 2;I;TAB 10;F(I);TAB 18;E(I)
416 NEXT I
417 DATA 6,6.00,"LUTHER LAKE","100 YR"
418 DATA .046,.078,.199,.490,.125,.063
419 PRINT
421 PRINT
422 PRINT
423 PRINT
424 PRINT
425 PRINT
426 PRINT
427 PRINT
428 PRINT
429 CLS
430 GO TO 370
450 REM "Fld Hyd"
451 PRINT "LINE 1 OF DATA FILE IS TITLE OF STUDY"
452 PRINT "LINE 2 IS NUMBER OF UNIT GRAPH ORDINATES,TIME INTERVAL,NUMBER OF RAINFALL EXCESSES"
453 PRINT "LINES 3 & 4 - UNIT GRAPH"
454 PRINT "LINE 5 & 6 - RAINFALL DATA"
455 PRINT "DATA STARTS WITH LINE 600"
456 DIM Q(30): DIM P(15): DIM U(15)
457 READ T$
458 READ NUHGQ,TR,NP
459 FOR I=1 TO NUHGQ
460 READ U(I)
461 NEXT I
462 FOR J=1 TO NP
463 READ P(J)
464 NEXT J
465 PAUSE 80
466 CLS
467 PRINT TAB 10;"FLOOD HYDROGRAPH"
468 PRINT TAB 16;"FOR"
469 PRINT
470 PRINT TAB 10;T$
471 PRINT
472 LET IHR=0
473 LET NQ=NP+NUHGQ-1
474 PRINT TAB 10;"IHR";TAB 16;"FLOW"
475 PRINT
476 FOR J=1 TO NQ
477 LET SUMF=0
478 IF (J-NUHGQ)>0 THEN GO TO 485
479 FOR I=1 TO J
480 LET K=J+1-I
481 LET Q(J)=P(K)*U(I)
482 LET SUMF=SUMF+Q(J)
483 NEXT I
484 GO TO 506
485 LET J1=J-NUHGQ+1
486 FOR I=J1 TO NP
487 LET K=J+1-I
488 LET Q(J)=P(I)*U(K)
489 LET SUMF=SUMF+Q(J)
490 NEXT I
491 GO TO 506
492 IF (J-NUHGQ)>0 THEN GO TO 506
493 FOR I=1 TO NP
494 LET K=J+1-I
495 LET Q(J)=P(I)*U(K)
496 LET SUMF=SUMF+Q(J)
497 NEXT I
498 GO TO 506
499 LET J1=J-NUHGQ+1
500 IF (J1-NP)>0 THEN GO TO 506
501 FOR I=J1 TO NP
502 LET K=J+1-I
503 LET Q(J)=P(I)*U(K)
504 LET SUMF=SUMF+Q(J)
505 NEXT I
506 LET IHR=IHR+1*TR
507 PRINT
508 PRINT TAB 10;IHR;TAB 16;SUMF
509 NEXT J
510 DATA "Willow lake 50 yr "
511 DATA 12,.5,12
512 DATA 93,632,489,220,83,30,11,4
513 DATA 1,0,0,0
514 DATA .11,.15,.20,.24,.36,.70,1.83
515 DATA .84,.41,.27,.20,.15
520 PRINT : PRINT : PRINT : PRINT : PRINT : PRINT : PRINT : PRINT
525 GO TO 372
550 REM "FUNC RATES"
551 PRINT "S+Q/2 AND S-Q/2 DATA"
552 PRINT TAB 7;"FOR"
553 DIM H(10): DIM A(10): DIM Q(10): DIM S(10): DIM B(10): DIM C(10): DIM D(10)
554 READ N,ELEVD,TR
555 FOR I=1 TO N
556 READ H(I),A(I),Q(I)
557 NEXT I
558 LET SUM=0
559 LET T$="Willow Lake"
560 FOR I=2 TO N
561 LET S(I)=((A(I)+A(I-1))/2+SUM)*ELEVD
562 LET SUM=S(I)
563 LET B(I)=S(I)*43560/10800
564 LET NUM=B(I)*10
565 LET B(I)=INT NUM/10
566 LET C(I)=B(I)-(Q(I))/2
567 LET D(I)=B(I)+(Q(I))/2
568 NEXT I: PRINT
569 PRINT TAB 8;T$
570 PRINT
571 PRINT "HEAD";TAB 6;"AREA";TAB 12;"DISCH";TAB 18;"STORAGE"
572 PRINT
573 FOR I=1 TO N
574 PRINT H(I);TAB 6;A(I);TAB 12;Q(I);TAB 18;S(I)
575 NEXT I
576 PRINT
577 PRINT "HEAD";TAB 6;"S/TR";TAB 12;"S/TR-Q/2";TAB 21;"S/TR+Q/2"
578 PRINT
579 FOR I=1 TO N
580 PRINT H(I);TAB 5;B(I);TAB 13;C(I);TAB 21;D(I)
581 NEXT I
582 PRINT "PLOT THIS DATA ON LOG-LOG PAPER"
583 DATA 6,1,1
584 DATA 0,670,0,1,700,950
585 DATA 2,730,2680,3,760,4940
586 DATA 4,790,7600,5,820,10620
587 PRINT
595 GO TO 372
1000 STOP
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
