Lecture 12 - Midterm Review
Welcome to Review Day!
You've learned a lot in just a few weeks! Today we'll:
- Review key concepts you need to master for the midterm
- Practice with interactive questions
- Clarify what you need to know vs. what's just context
- Build confidence for the exam
Reminders about the exam
- Friday, 12:20-1:10
- No reference sheets or calculators
- Two exam versions and set (but not assigned) seating
How Today Works
- Quick concept review for each topic
- Quick questions think-pair-share and cold calls
Development Tools
Shell/Terminal Commands (Lecture 2)
For the midterm, you should recognize and recall:
pwd- where am I?ls- what's here?ls -la- more info and hidden filesmkdir folder_name- make a foldercd folder_name- move into a foldercd ..- move up to a parent foldercd ~- return to the home directoryrm filename- delete a file
You DON'T need to: Memorize complex command flags or advanced shell scripting
Git Commands (Lecture 3)
For the midterm, you should recognize and recall:
git clone- get a repository, pasting in the HTTPS or SSH linkgit status- see what's changedgit checkout branch_name- switch to a different branchgit checkout -b new_branch- create a branch callednew_branchand switch to itgit add .- stage all recent changesgit commit -m "my commit message"- create a commit with staged changesgit push- send what's on my machine to GitHubgit pull- get changes from GitHub to my machine
You DON'T need to: merge, revert, reset, resolving merge conflicts, pull requests
Cargo Commands (Lecture 5)
For the midterm, you should recognize and recall:
cargo new project_name- create projectcargo run- compile and runcargo run --release- compile and run with optimizations (slower to compile, faster to run)cargo build- just compile without runningcargo check- just check for errors without compilingcargo test- run tests
You DON'T need to: Cargo.toml syntax, how Cargo.lock works, advanced cargo features
Quick Questions: Tools
Question 1
Which command shows your current location on your machine?
Question 2
What's the correct order for the basic Git workflow?
- A) add → commit → push
- B) commit → add → push
- C) push → add → commit
- D) add → push → commit
Question 3
Which cargo command compiles your code without running it?
Rust Core Concepts
Compilers vs Interpreters (Lecture 4)
Key Concepts
- Compiled languages (like Rust): Code is transformed into machine code before running
- Interpreted languages (like Python): Code is executed line-by-line at runtime
- The compiler checks your code for errors and translates it into machine code
- The machine code is directly executed by your computer - it isn't Rust anymore!
- A compiler error means your code failed to translate into machine code
- A runtime error means your machine code crashed while running
Rust prevents runtime errors by being strict at compile time!
Variables and Types (Lecture 7)
Key Concepts
- Defining variables:
let x = 5; - Mutability: Variables are immutable by default, use
let mutto allow them to change - Shadowing:
let x = x + 1;creates a newxvalue withoutmutand lets you change types - Basic types:
i32,f64,bool,char,&str,String - Rough variable sizes: Eg.
i32takes up 32-bits of space and its largest positive value is about half ofu32's largest value - Type annotations: Rust infers types (
let x = 5) or you can specify them (let x: i32 = 5) - Tuples: Creating (
let x = (2,"hi")), accessing (let y = x.0 + 1), destructuring (let (a,b) = x) - Constants: Eg.
const MY_CONST: i32 = 5, always immutable, must have explicit types, written into machine code at compile-time
What's Not Important
- Calculating exact variable sizes and max values
- 2's complement notation for negative integers
- Complex string manipulation details
String vs &str - You're not responsible for it, but let's talk about it
Quick explanation
String= a string = owned text data (like a text file you own)&str= a "string slice = borrowed text data (like looking at someone else's text)- A string literal like
"hello"is a&str(you don't own it, it's baked into your program) - To convert from an &str to a String, use
"hello".to_string()orString::from("hello") - To convert from a String to an &str, use
&my_string(to create a "reference")
Don't stress! You can do most things with either one, and I will not make you do anything crazy with these / penalize you for misusing these on the midterm.
Quick Questions: Rust basics
Question 4
What happens with this code?
#![allow(unused)] fn main() { let x = 5; x = 10; println!("{}", x); }
- A) Prints 5
- B) Prints 10
- C) Compiler error
- D) Runtime error
Question 5
What's the type of x after this code?
#![allow(unused)] fn main() { let x = 5; let x = x as f64; let x = x > 3.0; }
- A)
i32 - B)
f64 - C)
bool - D) Compiler error
Question 6
How do you access the second element of tuple t = (1, 2, 3)?
- A)
t[1] - B)
t.1 - C)
t.2 - D)
t(2)
Functions (Lecture 8)
Key Concepts
- Function signature:
fn name(param1: type1, param2: type2) -> return_type, returned value must matchreturn_type - Expressions and statements: Expressions reduce to values (no semicolon), statements take actions (end with semicolon)
- Returning with return or an expression: Ending a function with
return x;andxare equivalent - {} blocks are scopes and expressions: They reduce to the value of the last expression inside them
- Unit type: Functions without a return type return
() - Best practices: Keep functions small and single-purpose, name them with verbs
What's Not Important
- Ownership/borrowing mechanics (we'll cover this after the midterm)
- Advanced function patterns
Quick Questions: Functions
Question 7
What is the value of mystery(x)?
#![allow(unused)] fn main() { fn mystery(x: i32) -> i32 { x + 5; } let x = 1; mystery(x) }
- A) 6
- B)
i32 - C)
() - D) Compiler error
Question 8
Which is a correct function signature for a function that takes two integers and returns their sum?
Question 9
Which version will compile
#![allow(unused)] fn main() { // Version A fn func_a() { 42 } // Version B fn func_b() { 42; } }
- A) A
- B) B
- C) Both
- D) Neither
Question 10
What does this print?
#![allow(unused)] fn main() { let x = println!("hello"); println!("{:?}", x); }
- A) hello /n hello
- B) hello /n ()
- C) hello
- D) ()
- E) Compiler error
- F) Runtime error
Loops and Arrays (Lecture 9)
Key Concepts
- Ranges:
1..5vs1..=5 - Arrays: Creating (
[5,6]vs[5;6]), accessing (x[i]), 0-indexing - If/else: how to write
if / elseblocks with correct syntax - Loop types:
for,while,loop- how and when to use each breakandcontinue: For controlling loop flow- Basic enumerating
for (i, val) in x.iter().enumerate()
What's Not Important
- Compact notation (
let x = if y ...orlet y = loop {...) - Enumerating over a string array with
for (i, &item) in x.iter().enumerate() - Labeled loops, breaking out of an outer loop
Quick Questions: Loops & Arrays
Question 11
What's the difference between 1..5 and 1..=5?
Question 12
What does this print?
#![allow(unused)] fn main() { for i in 0..3 { if i == 1 { continue; } println!("{}", i); } }
Question 13
How do you get both index and value when looping over an array?
Enums and Pattern Matching (Lecture 10)
Key Concepts
- Enum definition: Creating custom types with variants
- Data in variants: Enums can hold data
matchexpressions: syntax by hand, needs to be exhaustive, how to use a catch-all (_)Option<T>: HasSome(value)andNoneResult<T, E>: HasOk(value)andErr(error)#[derive(Debug)]: For making enums printable#[derive(PartialEq)]: For allowing enums to be compared with==and!=- Data extraction: Getting values out of enum variants with
match,unwrap, orexpect
What's Not Important
if letnotation- writing complex matches (conditional statements, ranges, tuples) - you should understand them but don't have to write them
Quick Questions: Enums & Match
Question 14
What's wrong with this code?
#![allow(unused)] fn main() { enum Status { Loading, Complete, Error, } match Status::Loading { Status::Loading => println!("Loading..."), Status::Complete => println!("Done!"), } }
Question 15
If a function's return type is Option<i32> what values can it return (can be more than one)?
- A)
Some(i32) - B)
Ok - C)
Ok(i32) - D)
None - E)
Err
Question 16
What can go in the ???? to get the value out of Some(42)?
#![allow(unused)] fn main() { let x = Some(42); match x { Some(????) => println!("Got: {}", ????), None => println!("Nothing"), } }
- A)
_and_ - B)
42and42 - C)
xandx - D)
yandy
Question 17
What does #[derive(Debug)] do?
Error Handling (Lecture 11)
Key Concepts
panic!vsResult: Panic when unrecoverable, Result when recoverableResult<T, E>for errors:Ok(value)for success,Err(error)for failure- Error propagation: Passing errors up with
matchor? unwrap()andexpect(): Quick ways to extract values (but they can panic!)- The
?operator: Shortcut for "if error, return it; if ok, give me the value" - only works on sharedE
Quick Questions: Error Handling
Question 18
When should you use panic! vs Result<T, E>?
Question 19
Why won't this code compile?
#![allow(unused)] fn main() { fn parse_number(s: &str) -> Result<i32, String> { let num = s.parse::<i32>()?; // parse() returns Result<i32, ParseIntError> Ok(num * 2) } }
- A) The
?operator can't be used inletstatements - B) You can't multiply by 2 inside
Ok() - C) The error types don't match:
ParseIntErrorvsString - D)
Okdoesn't match theResulttype
Question 20
When might you extract a value with .unwrap()?
- A) When you're pretty sure the value will be
Ok/SomenotErr/None - B) When you want the code to crash if the value is
ErrorNone - C) When you want the value if
Ok/Somebut want to ignore it ifErr/None - D) When you want a more concise version of a match statement
Question 21
What does this return when called with divide(10, 2)?
#![allow(unused)] fn main() { fn divide(a: i32, b: i32) -> Result<i32, String> { if b == 0 { Err("Can't divide by zero".to_string()) } else { Ok(a / b) } } }
Putting It All Together
What You've Accomplished
In just a few weeks, you've learned:
- Professional development tools (shell, git, github, cargo)
- The foundations of a systems programming language
- Sophisticated pattern matching and error handling techniques
That's genuinely impressive!
And if it doesn't feel fluent yet, give it some time. It's like you memorized your first 500 words in a new spoken language but haven't had much practice actually speaking it yet. It feels awkward, and that's normal.
Midterm Strategy
- Focus on concepts: Understand the "why" behind the syntax and it will be easier to remember
- Practice with your hands: Literally and figuratively - practice solving problems, and practice on paper
- Take big problems step-by-step: Understand each line of code before reading the next. And make a plan before you start to hand-code
Questions and Discussion
What topics would you like to clarify before Wednesday's practice session?
Activity Time - Design your own midterm
No promises, but I do mean it.
You'll find an activity released to you on gradescope to do solo or in groups.
I want you all to spend some time thinking about problems/questions that you could imagine being on our first midterm. If I like your questions, I might include them (or some variation) on the exam!
This also helps me understand what you're finding easy/difficult and where we should focus on Wednesday. It can help you identify areas you might want to brush up on as well.
Aim to come up with 2-3 questions per category (or more!). I'm defining these as:
- EASY You know the answer now and expect most students in the class will get it right
- MEDIUM You feel iffy now but bet you will be able to answer it after studying, and it would feel fair to be on exam
- HARD It would be stressful to turn the page to this question, but you bet you could work your way to partial credit
Requirements for each question:
For each question you create, please include:
- The question itself
- The answer/solution (if you can solve it)
- Why you categorized it as Easy/Medium/Hard
Content Areas to Consider:
Make sure your questions collectively cover the major topics we've studied so far:
- Tools: git, shell, cargo
- Rust: Variables, types, functions, loops, enums & match, error handling
Some formats of problems to consider:
- Definitions
- Multiple choice
- Does this compile / what does it return
- Find and fix the bug
- Fill-in-the-blank in code
- Longer hand-coding problems
- Short answer on concepts (describe how x works...)