Skip to content
ExamSpine

Lesson 3.10

Capstone: read a stream, report several statistics

Part 3: RepetitionReading, about 5 min1 exercise in this lesson

Java answers can't run on Spine yet. You can still read Java, trace it, and put an answer's lines in order.

Planning a program that reports on a stream of numbers

By the end of this you will be able to plan a program that reads numbers until a stop value and reports several facts about them, and keep track of the largest number so far.

This lesson puts Part 3 together. A stream is a run of inputs whose length you do not know in advance, ended by a stop value. You already know how to count a stream, add it up and guard against an empty one. Here you do several of these in one loop, and add one new idea: the largest so far.

Plan with a table

Before you write any code, list every line the program prints. Then make a table with one row for each fact the program reports. For each one, write what it starts at and what each new number does to it.

A shop types in the price of each sale, in whole dollars from 1 to 500, and types 0 when the day ends. The program prints how many sales there were, the biggest sale, and how many sales were over 100. If 0 comes first, it prints No sales.

FactStarts asWhat each sale does
count0Adds 1
biggest0 until the first sale sets itReplaces it if the sale is bigger
over0Adds 1 if the sale is over 100

Each row becomes one variable, started before the loop and updated in its body. All of them share one loop.

The largest so far

A count and a total start at 0, because before the first number nothing has been counted or added. The biggest sale is different. Before any sale there is no biggest sale. But once one sale has been read, that sale is the biggest so far, because it is the only one. From then on, each new sale either beats the biggest so far and replaces it, or it does not and the biggest stays.

So the first sale sets biggest, and every later sale is compared with it. The count tells you which sale is the first: if the count goes up before the check, a count of 1 means this is the first.

The program

sale = int(input())
count = 0
biggest = 0
over = 0
while sale != 0:
    count = count + 1
    if count == 1:
        biggest = sale
    elif sale > biggest:
        biggest = sale
    if sale > 100:
        over = over + 1
    sale = int(input())
if count == 0:
    print("No sales")
else:
    print("Sales: " + str(count))
    print("Biggest: " + str(biggest))
    print("Over 100: " + str(over))
import java.util.Scanner;

public static void main(String[] args) {
    Scanner scanner
        = new Scanner(System.in);
    int sale = Integer.parseInt(
        scanner.nextLine());
    int count = 0;
    int biggest = 0;
    int over = 0;
    while (sale != 0) {
        count = count + 1;
        if (count == 1) {
            biggest = sale;
        } else if (sale > biggest) {
            biggest = sale;
        }
        if (sale > 100) {
            over = over + 1;
        }
        sale = Integer.parseInt(
            scanner.nextLine());
    }
    if (count == 0) {
        System.out.println("No sales");
    } else {
        System.out.println(
            "Sales: " + count);
        System.out.println(
            "Biggest: " + biggest);
        System.out.println(
            "Over 100: " + over);
    }
}

biggest starts at 0 only so that it has a value. The first sale replaces it before it is ever printed.

If the user types 40, 120, 75 and then 0, the program prints:

Sales: 3
Biggest: 120
Over 100: 1

The shape is the one from the lessons on while loops. Read the first number before the loop, so the condition has something to check. Read the next number as the last line of the body, so the stop value is checked before anything counts it. Print after the loop, once every fact is final, and only when the count is not 0.

The biggest check and the over-100 check are separate ifs, not one chain. A sale can be the biggest so far and over 100 at the same time, and both facts must change.

Test it on purpose

Pick inputs that each try one part of the plan:

  • 0 first: the count is 0, so the program prints No sales.
  • One sale: it is the biggest.
  • A biggest sale that is not the first one, such as 40, 120, 75: the comparison must replace it.
  • A sale of exactly 100: it is not over 100.

A common mistake: starting a "smallest so far" at 0 and comparing every number with it. If no number can be below 0, nothing ever beats it, and the smallest stays 0. Starting from the first number works whatever the numbers are.

Now try it yourself on the questions below.

Exercise 3.10.13.10.1 · Write itStream statistics

Write a program that reads whole numbers one at a time, stopping at -1, and reports five statistics about the numbers it read.

  1. Read one number per line. The value -1 means "no more numbers" and is not counted as data.
  2. If at least one number was entered, print five lines in this order:
  • Count: followed by how many numbers were entered.
  • Sum: followed by their total.
  • Average: followed by the whole-number average (drop the fraction).
  • Min: followed by the smallest number.
  • Max: followed by the largest number.
  1. If -1 is typed first (no data), print No data.

All numbers are whole numbers from 0 to 1000. Your program is run several times. Only what it prints is checked.

In Python, use // for whole-number division. In Java, / between two ints already drops the fraction.

Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.

Examples

Your program is run 7 times: the 3 examples below, and 4 hidden ones that check the rules above. Only what it prints is checked.

  • three numbers (rule 2)

    You type

    1. typed: 10
    2. typed: 20
    3. typed: 30
    4. typed: -1

    It prints

    Count: 3
    Sum: 60
    Average: 20
    Min: 10
    Max: 30
  • no data at all (rule 3)

    You type

    1. typed: -1

    It prints

    No data
  • one number, all stats equal (rule 2)

    You type

    1. typed: 5
    2. typed: -1

    It prints

    Count: 1
    Sum: 5
    Average: 5
    Min: 5
    Max: 5
solution.pySolution.java