Skip to content

Commit 9b30a61

Browse files
author
Dana Binkley
committed
Merge branch 'mr/486-create-lab-for-module-common-library-types' into 'master'
Resolve "Create Lab for Module: Common Library Types" Closes #486 See merge request feng/training/material!562
2 parents b1eba24 + 010b61c commit 9b30a61

5 files changed

Lines changed: 107 additions & 65 deletions

File tree

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,17 @@
1-
===================
2-
Exercise: Counter
3-
===================
1+
=====
2+
Lab
3+
=====
44

5-
-------------------
6-
Counter Problem
7-
-------------------
5+
------------------
6+
Lab Instructions
7+
------------------
88

9-
In this exercise you will take a very simple data structure and make it
10-
generic. It uses a
11-
:url:`std::collections::HashMap <https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html>`
12-
to keep track of which values have been seen and how many times each one
13-
has appeared.
9+
- Solve for compilation errors
1410

15-
The initial version of :rust:`Counter` is hard coded to only work for
16-
:rust:`u32` values. Make the struct and its methods generic over the type of
17-
value being tracked, that way :rust:`Counter` can track any type of value.
11+
- Follow the hints!
1812

19-
If you finish early, try using the
20-
:url:`entry <https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.entry>`
21-
method to halve the number of hash lookups required to implement the
22-
:rust:`count` method.
13+
- Success is
2314

24-
::
25-
26-
use std::collections::HashMap;
27-
28-
/// Counter counts the number of times each value of type T has been seen.
29-
struct Counter {
30-
values: HashMap<u32, u64>,
31-
}
32-
33-
impl Counter {
34-
/// Create a new Counter.
35-
fn new() -> Self {
36-
Counter {
37-
values: HashMap::new(),
38-
}
39-
}
40-
41-
/// Count an occurrence of the given value.
42-
fn count(&mut self, value: u32) {
43-
if self.values.contains_key(&value) {
44-
*self.values.get_mut(&value).unwrap() += 1;
45-
} else {
46-
self.values.insert(value, 1);
47-
}
48-
}
49-
50-
/// Return the number of times the given value has been seen.
51-
fn times_seen(&self, value: u32) -> u64 {
52-
self.values.get(&value).copied().unwrap_or_default()
53-
}
54-
}
55-
56-
------------------------
57-
Counter - Main Program
58-
------------------------
59-
60-
.. container:: source_include 110_common_library_types/src/110_common_library_types.rs :start-after://ANCHOR-main :code:rust :number-lines:1
61-
62-
-------------------
63-
Counter Solution
64-
-------------------
65-
66-
.. container:: source_include 110_common_library_types/src/110_common_library_types.rs :start-after://ANCHOR-solution :end-before://ANCHOR-main :code:rust :number-lines:1
15+
- Code that compiles
6716

17+
- ...and that follows any behavior indicated within the hints!

courses/rust_essentials/110_common_library_types/lab/answer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "lab"
2+
name = "answer"
33
version = "1.0.0"
44
edition = "2024"
55

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,52 @@
1+
//! Lab (answer)
2+
//! Common Library Types
3+
//!
4+
#[allow(dead_code)]
5+
#[allow(unused_variables)]
16
fn main() {
2-
println!("TBD");
7+
8+
// TASK 1 - 'Option' Type Handling
9+
// Hint: 'Option<T>' must be explicitly handled
10+
let maybe_number = Some(42);
11+
let result = match maybe_number {
12+
Some(v) => v + 10,
13+
None => 0,
14+
};
15+
println!("TASK1 => result: {}", result);
16+
17+
// TASK 2 - 'Result' Variants
18+
// Hint: 'Result' uses 'Ok(T)' and 'Err(E)'
19+
fn check_positive(num: i32) -> Result<i32, String> {
20+
if num > 0 {
21+
Ok(num) // Replaced Some with Ok
22+
} else {
23+
Err(String::from("Not a positive number")) // Replaced None with Err
24+
}
25+
}
26+
println!("TASK2 => check: {:?}", check_positive(-5));
27+
28+
// TASK 3 - 'String' vs '&str'
29+
// Hint: '&str' is a fixed view, an owned and growable 'String' is needed to append text
30+
let mut greeting = String::from("Hello"); // Converted to an owned 'String'
31+
greeting.push_str(" world");
32+
println!("TASK3 => greeting: {}", greeting);
33+
34+
// TASK 4 - Modifying Strings ('push' vs 'push_str')
35+
// Hint: Which 'String' method appends a slice instead of a single 'char'?
36+
let mut text = String::from("Rust");
37+
text.push_str(" is great"); // Changed 'push' to 'push_str'
38+
println!("TASK4 => text: {}", text);
39+
40+
// TASK 5 - Vector Creation Macro
41+
// Hint: How is a macro invoked differently than a function?
42+
let numbers = vec![1, 2, 3]; // Added '!' to properly invoke the macro
43+
println!("TASK5 => numbers length: {}", numbers.len());
44+
45+
// TASK 6 - Representing Absence
46+
// Hint: Rust does not have null pointers, absence is represented by the appropriate 'Option' variant
47+
fn get_user(id: u32) -> Option<String> {
48+
None // Replaced null with 'None'
49+
}
50+
println!("TASK6 => get_user(1): {:?}", get_user(1));
51+
352
}

courses/rust_essentials/110_common_library_types/lab/prompt/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "lab"
2+
name = "prompt"
33
version = "1.0.0"
44
edition = "2024"
55

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,46 @@
1+
//! Lab (prompt)
2+
//! Common Library Types
3+
//!
4+
//! Fix all the compile errors below by following the hints provided
5+
//!
6+
#[allow(dead_code)]
7+
#[allow(unused_variables)]
18
fn main() {
2-
println!("TBD");
9+
10+
// TASK 1 - 'Option' Type Handling
11+
// Hint: 'Option<T>' must be explicitly handled
12+
let maybe_number = Some(42);
13+
let result = maybe_number + 10;
14+
15+
// TASK 2 - 'Result' Variants
16+
// Hint: 'Result' uses 'Ok(T)' and 'Err(E)'
17+
fn check_positive(num: i32) -> Result<i32, String> {
18+
if num > 0 {
19+
Some(num)
20+
} else {
21+
None
22+
}
23+
}
24+
25+
// TASK 3 - 'String' vs '&str'
26+
// Hint: '&str' is a fixed view, an owned and growable 'String' is needed to append text
27+
let mut greeting = "Hello";
28+
greeting.push_str(" world");
29+
30+
// TASK 4 - Modifying Strings ('push' vs 'push_str')
31+
// Hint: Which 'String' method appends a slice instead of a single 'char'?
32+
let mut text = String::from("Rust");
33+
text.push(" is great");
34+
35+
// TASK 5 - Vector Creation Macro
36+
// Hint: How is a macro invoked differently than a function?
37+
let numbers = vec[1, 2, 3];
38+
39+
// TASK 6 - Representing Absence
40+
// Hint: Rust does not have null pointers, absence is represented by the appropriate 'Option' variant
41+
fn get_user(id: u32) -> Option<String> {
42+
null
43+
}
44+
println!("TASK6 => get_user(1): {:?}", get_user(1));
45+
346
}

0 commit comments

Comments
 (0)