C++ Vector Practice: Build a Data Summary
Build a tested C++ vector data-summary program with validated input, separate functions, bounded arithmetic, minimum, maximum, mean and explicit empty handling.
What you will learn
- Separate parsing, storage, calculation and output responsibilities.
- Specify empty-summary behavior before reading the first element.
- Use bounded sums and floating division for a meaningful mean.
- Keep extrema correct for negative and repeated readings.
- Validate the design with discriminating boundary-case transcripts.
A sequence-summary program starts with a contract
A useful report needs more than a loop that happens to add some numbers. Decide which input is accepted, what each reported field means, and what happens when no records are present. This lab accepts a count from zero through eight followed by that many integer readings from minus one hundred through one hundred. Each required record occupies one complete line. There is one report per execution, not an unbounded streaming session.
The output contains count and sum for every accepted collection. A nonempty collection also has a minimum, maximum and arithmetic mean displayed with two decimal places. An empty collection instead prints No readings after its zero count and zero sum. It does not claim a minimum of zero, a maximum of zero or a mean of zero, because those labels would conceal the absence of data rather than explain it.
Write these rules before choosing function names. They decide which states your code must represent and which tests should fail. The lab is not a statistics package: it does not infer missing samples, estimate uncertainty, reject outliers or measure a physical unit. Integer readings and a small explicit bound keep the application understandable while still requiring careful reasoning about empty input, negative values and arithmetic conversion.
Separate collection, calculation and presentation
A parser should answer whether a complete line contains one valid integer representation. The collector adds the application's count and reading bounds. A calculation function should receive accepted data rather than reading from std::cin itself. Presentation writes the chosen labels and formatting. These responsibilities may live in one source file at this stage; separation is about contracts and dependencies, not automatically creating a new class or file for every small operation.
Pass the vector to a read-only calculation function as const std::vector<int>&. The reference avoids copying the entire collection for each query, while const prevents modification through that parameter. A function that returns an integer sum can be tested with an already constructed vector, independent of terminal parsing. That makes it easier to locate a failure: a wrong total in a pure calculation is not an input-buffer problem.
Keep this design proportional to the task. The reference solution extracts totalOf but leaves a short validated collection phase and explicit report branching in main. There is no need to introduce a general framework before the class lessons. As the application grows, a structured summary result can group related fields. For now, named local values, a clear empty guard and one focused calculation function make the information flow reviewable.
Test a calculation without terminal input
The function observes its vector and returns a bounded sum. Its behavior does not depend on cin, cout or a hidden mutable global.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Empty: 0
Mixed: 0
After editing inputs, calculate a new prediction; this reference describes only the starter.
Initialize extrema from data, not an invented neutral value
Zero is an identity for addition, but it is not a universal starting minimum or maximum. If every reading is negative, starting maximum at zero produces a value that never appeared in the data. If every reading is positive, starting minimum at zero makes the same mistake in the opposite direction. Once you know the vector is nonempty, initialize both extrema from its first actual element and then compare accepted values.
The empty check must precede front(). A variable holding a default zero cannot turn a nonexistent element into a valid observation. In the reference solution, the empty branch prints its explicit absence label and returns before either extremum is initialized from data. This makes the precondition visible in control flow. You can then review the remaining branch with the established fact that at least one reading exists.
Repeated extrema do not need special treatment: comparing equal values leaves the same minimum or maximum in place. A single reading supplies both extrema and its own mean. Test all-negative, all-positive, repeated and single-value collections because each targets a distinct assumption. A mixture containing zero would not expose every faulty zero-initialization strategy, so it is a weak sole test even when its final report looks reasonable.
Trace an all-negative collection
Starting from the first accepted reading avoids inventing a maximum of zero.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Min: -8
Max: -3
After editing inputs, calculate a new prediction; this reference describes only the starter.
Bound the sum and convert before dividing
Eight readings between minus one hundred and one hundred constrain the sum to the interval from minus eight hundred through eight hundred. An int accumulator is sufficient for that declared contract. Passing arbitrary unbounded data to the same helper would require a different arithmetic analysis. Using a vector or a const reference does not prevent integer overflow; the accepted values and count establish the bound, not the container syntax.
The arithmetic mean requires floating division when a fractional result matters. Convert the sum to double before dividing by the count, and make the count conversion explicit as well. Converting an already truncated integer quotient afterwards cannot restore its discarded fraction. The empty branch prevents division by zero before any conversion is attempted. Keep these two proofs separate: nonzero denominator and intended arithmetic type solve different problems.
Use std::fixed with std::setprecision(2) to define the display contract rather than relying on the stream's default representation. This rounds the displayed result; it does not make binary floating-point exact decimal arithmetic. Avoid presenting a temperature or monetary precision guarantee the program does not provide. The lab prints a simple numeric demonstration in the default stream locale and keeps exact integer count, sum and extrema alongside the formatted mean.
Reject partial input and preserve evidence of the first failure
If a required line is missing or malformed, print Invalid input and return status one without a summary. Reading only the valid prefix of 12abc would make the report appear more complete than it is. Parse an integer, consume trailing whitespace, and require end-of-line. A final valid line does not need a newline character after it. Extra lines after all requested records remain outside this single-report protocol and are not silently counted as additional readings.
Build a small test matrix whose cases answer different questions. Count zero checks the absence branch; a single negative value checks extrema; two readings with a fractional mean check conversion; repeated values check stable comparisons; eight endpoint values check accepted bounds. Add an overflowing integer token, a negative count, a count above eight, an invalid reading, a numeric suffix and early end-of-input to verify rejection happens before success output.
A repair exercise is to intentionally calculate the mean with integer division in your own copy, observe the failure on readings one and two, then restore conversion before division. Another is to initialize maximum to zero and test an all-negative collection. Keep the failed prediction, actual transcript and corrected reasoning in your lab notes. These are deterministic logic defects; do not introduce undefined behavior just to manufacture a debugging demonstration.
Compile and test outside the lesson
The compiler-backed editors support complete single-file programs when the execution service is available. Otherwise save one program as main.cpp and run these commands with your configured compiler. Supply all standard input before Run; this is not an interactive terminal.
macOS / Linux (choose your installed compiler):
clang++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
# Or: g++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
./lesson
Windows Developer Command Prompt:
cl /std:c++20 /EHsc /W4 main.cpp /Fe:lesson.exe
lesson.exeIndependent lab
Build a complete reading report with validated collection, a pure total function and an explicit empty-data branch.
Acceptance checklist
- Read a count from 0 through 8 and that many integer lines in -100 through 100.
- Reject malformed, missing and out-of-range required input with Invalid input and status 1 before any summary.
- Use a const-reference total function with no terminal I/O.
- Print Count and Sum, then No readings for empty data; otherwise print Min, Max and Mean.
- Initialize extrema from actual data and display floating mean to two decimal places.
Need a hint?
- Prove values is nonempty before using front or dividing by size.
- Test all-negative readings to expose a fictional zero maximum.
- Convert sum before division; 1 and 2 should have mean 1.50.
Write and run your lab
Build your own solution before revealing the reference. Use the input field for normal, boundary and invalid cases; this runner executes your program but does not grade it.
Predict the output, edit the source, then select Run code.
Your lab evidence and notes
Record predictions, actual output, commands and the cause of each repair. Code is plain text: this scratchpad does not execute or grade C++.
Loading local notes…
Review your acceptance checklist and quiz explanations before marking this lesson complete. This is self-review, not a grade or certification.
Reveal the explained lab solution
Reference lab solution
Compare the reference with your own reasoning. Running this solution does not grade or complete the lesson.
Predict the output, edit the source, then select Run code.
Expected output
Count: 3
Sum: 3
Min: -4
Max: 6
Mean: 1.00
The collector establishes the count and value bounds before totalOf is used, limiting the sum's magnitude to eight hundred.
The empty branch gives absence its own output and prevents invalid first-element access and zero-denominator division.
Extrema start from real data; double conversion happens before division and formatting defines display rather than mathematical exactness.
Review before moving on
Explain the lesson's objectives in your own words, compare your lab evidence with the acceptance checklist, and keep the first failing case alongside your repair. Completing a page is not proof that every C++ feature or input is supported.
- Separate parsing, storage, calculation and output responsibilities.
- Specify empty-summary behavior before reading the first element.
- Use bounded sums and floating division for a meaningful mean.
- Keep extrema correct for negative and repeated readings.
- Validate the design with discriminating boundary-case transcripts.
References and further reading
Original examples and exercises accompany these primary references. Tool-specific diagnostics and support depend on your installed version.