Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Activity 3: Put the Program Together

The scenario

You are writing a small program to help you keep track of your quiz scores. It should:

  1. Start with the scores you already have
  2. Add a new score you just got back
  3. Work out the average
  4. Print a different message depending on how you are doing

You have all the pieces below, but they are in the wrong order. Some of them are commands you type in the shell, and some of them are lines of Rust that go inside your program file.

Directions

  • Get in groups of 2-3
  • Send one person up to get a packet
  • Write everyone's names on the submission sheet

Do a quick check of your strips: you should have 24, all different. If you are missing any, check out the list on the screen and make any you're missing out of scrap.

Sort the strips into two columns on the page:

  • Your shell: Things you type at the terminal, in the order you'd type them
  • Your file, src/main.rs: Lines of Rust, in the order they belong in the file

Things to think about as you go:

  • Order matters in both columns. Think about what has to exist before each step can work
  • Not every strip is essential. If you think something is optional, put it where you would actually use it and be ready to say why
  • You won't know what all the Rust stuff means yet, but do you know enough to make an educated guess?

We'll take the last few minutes to share solutions.

The strips

Cut along the dashed lines. One set per group.

  • println!("Good work! Average: {:.1}", average);
  • cargo run
  • scores.push(88);
  • let average = total as f64 / scores.len() as f64;
  • cargo new grade_calculator
  • } else if average >= 80.0 {
  • nano src/main.rs
  • let total: i32 = scores.iter().sum();
  • if average >= 90.0 {
  • touch README.md
  • ./target/debug/grade_calculator
  • fn main() {
  • cargo build
  • println!("Keep trying! Average: {:.1}", average);
  • let mut scores = vec![85, 92, 78, 96];
  • ls -la
  • cd grade_calculator
  • echo "This is a grade average calculator" > README.md
  • } else {
  • }
  • }
  • println!("Excellent! Average: {:.1}", average);
  • println!("You have {} scores so far.", scores.len());
  • cat src/main.rs

Sorting sheet

Names: _______________________________________________________________

Sort the strips into the two areas below. Order matters in both, for different reasons. Not every strip is essential; if you think one is optional, put it where you would actually use it and be ready to say why.

Your shell
Your file, src/main.rs

Solution

Shell column:

cargo new grade_calculator
cd grade_calculator
ls -la
touch README.md
echo "This is a grade average calculator" > README.md
nano src/main.rs
cat src/main.rs
cargo run

Or, for the last step, the two-step version:

cargo build
./target/debug/grade_calculator

src/main.rs column:

fn main() {
    let mut scores = vec![85, 92, 78, 96];
    scores.push(88);
    println!("You have {} scores so far.", scores.len());
    let total: i32 = scores.iter().sum();
    let average = total as f64 / scores.len() as f64;
    if average >= 90.0 {
        println!("Excellent! Average: {:.1}", average);
    } else if average >= 80.0 {
        println!("Good work! Average: {:.1}", average);
    } else {
        println!("Keep trying! Average: {:.1}", average);
    }
}

Which strips are optional

Several of the shell strips could be dropped without breaking the program:

  • ls -la and cat src/main.rs only look at things - they're good things to do but not essential, and could go a few places
  • touch README.md is redundant, because echo "..." > README.md on the next line creates the file anyway. So does >>, which appends but still creates the file if it isn't there.
  • echo "..." > README.md (and so the README entirely) is technically not needed to run the program. It is good practice, though!
  • cargo build plus ./target/debug/grade_calculator is the alternative to cargo run, not an addition to it. Either path is right, but you don't need both.

Nothing in the Rust column was designed to be optional.