Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous v2 improvements #1

Merged
merged 8 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
- [Named Structs](user-defined-types/named-structs.md)
- [Tuple Structs](user-defined-types/tuple-structs.md)
- [Enums](user-defined-types/enums.md)
- [Deriving](user-defined-types/deriving.md)
- [Static and Const](user-defined-types/static-and-const.md)
- [Type Aliases](user-defined-types/aliases.md)
- [Destructuring](user-defined-types/destructuring.md)
- [Let Control Flow](user-defined-types/let-control-flow.md)
Expand All @@ -74,6 +74,7 @@
- [Methods and Traits](methods-and-traits.md)
- [Methods](methods-and-traits/methods.md)
- [Traits](methods-and-traits/traits.md)
- [Deriving](methods-and-traits/deriving.md)
- [Trait Objects](methods-and-traits/trait-objects.md)
- [Exercise: GUI Library](methods-and-traits/exercise.md)
- [Solution](methods-and-traits/solution.md)
Expand Down Expand Up @@ -176,7 +177,6 @@
- [Unsafe Rust](unsafe-rust.md)
- [Unsafe](unsafe-rust/unsafe.md)
- [Dereferencing Raw Pointers](unsafe-rust/dereferencing.md)
- [Static and Const](unsafe-rust/static-and-const.md)
- [Mutable Static Variables](unsafe-rust/mutable-static.md)
- [Unions](unsafe-rust/unions.md)
- [Unsafe Functions](unsafe-rust/unsafe-functions.md)
Expand Down
27 changes: 0 additions & 27 deletions src/borrowing/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,6 @@ methods:
#![allow(unused_variables, dead_code)]

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:setup}}
{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_new}}
todo!("Create a new User instance")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_name}}
todo!("Return the user's name")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_age}}
todo!("Return the user's age")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_height}}
todo!("Return the user's height")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_doctor_visits}}
todo!("Return the number of time the user has visited the doctor")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_set_age}}
todo!("Set the user's age")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_set_height}}
todo!("Set the user's height")
}

{{#include ../../third_party/rust-on-exercism/health-statistics.rs:User_visit_doctor}}
todo!("Update a user's statistics based on measurements from a visit to the doctor")
Expand Down
2 changes: 2 additions & 0 deletions src/memory-management/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ Fill in the missing pieces.
}

{{#include exercise.rs:build}}

{{#include exercise.rs:main}}
```
35 changes: 35 additions & 0 deletions src/methods-and-traits/deriving.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
minutes: 5
existing course material:
- traits/deriving-traits.md
---

# Deriving

Supported traits can be automatically implemented for your custom types, as
follows:

```rust,editable
#[derive(Debug, Clone, Default)]
struct Player {
name: String,
strength: u8,
hit_points: u8,
}

fn main() {
let p1 = Player::default(); // Default trait adds `default` constructor.
let mut p2 = p1.clone(); // Clone trait adds `clone` method.
p2.name = String::from("EldurScrollz");
// Debug trait adds support for printing with `{:?}`.
println!("{:?} vs. {:?}", p1, p2);
}
```

<details>

Derivation is implemented with macros, and many crates provide useful derive
macros to add useful functionality. For example, `serde` can derive
serialization support for a struct using `#[derive(Serialize)]`.

</detail>
27 changes: 3 additions & 24 deletions src/methods-and-traits/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,11 @@ Copy the code below to <https://play.rust-lang.org/>, fill in the missing

{{#include exercise.rs:setup}}

{{#include exercise.rs:Label-width}}
unimplemented!()
}
// TODO: Implement `Widget` for `Label`.

{{#include exercise.rs:Label-draw_into}}
unimplemented!()
}
}

{{#include exercise.rs:Button-width}}
unimplemented!()
}

{{#include exercise.rs:Button-draw_into}}
unimplemented!()
}
}

{{#include exercise.rs:Window-width}}
unimplemented!()
}
// TODO: Implement `Widget` for `Button`.

{{#include exercise.rs:Window-draw_into}}
unimplemented!()
}
}
// TODO: Implement `Widget` for `Window`.

{{#include exercise.rs:main}}
```
Expand Down
13 changes: 0 additions & 13 deletions src/methods-and-traits/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,15 @@ impl Window {
)
}
}

// ANCHOR_END: setup

// ANCHOR: Window-width
impl Widget for Window {
fn width(&self) -> usize {
// ANCHOR_END: Window-width
// Add 4 paddings for borders
self.inner_width() + 4
}

// ANCHOR: Window-draw_into
fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {
// ANCHOR_END: Window-draw_into
let mut inner = String::new();
for widget in &self.widgets {
widget.draw_into(&mut inner);
Expand All @@ -113,16 +108,12 @@ impl Widget for Window {
}
}

// ANCHOR: Button-width
impl Widget for Button {
fn width(&self) -> usize {
// ANCHOR_END: Button-width
self.label.width() + 8 // add a bit of padding
}

// ANCHOR: Button-draw_into
fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {
// ANCHOR_END: Button-draw_into
let width = self.width();
let mut label = String::new();
self.label.draw_into(&mut label);
Expand All @@ -135,20 +126,16 @@ impl Widget for Button {
}
}

// ANCHOR: Label-width
impl Widget for Label {
fn width(&self) -> usize {
// ANCHOR_END: Label-width
self.label
.lines()
.map(|line| line.chars().count())
.max()
.unwrap_or(0)
}

// ANCHOR: Label-draw_into
fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {
// ANCHOR_END: Label-draw_into
writeln!(buffer, "{}", &self.label).unwrap();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/std-traits/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ fn main() {
rot.read_to_string(&mut result).unwrap();
println!("{}", result);
}
// ANCHOR_END: main

#[cfg(test)]
mod test {
Expand Down Expand Up @@ -80,3 +79,4 @@ mod test {
}
}
}
// ANCHOR_END: main
45 changes: 30 additions & 15 deletions src/std-types/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,49 @@ minutes: 5

# Exercise: Counter

In this exercise you will build a very simple data structure that counts the
number of times values are seen.

Use a
In this exercise you will take a very simple data structure and make it generic.
It uses a
[`std::collections::HashMap`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html)
to implement your `Counter` type.
to keep track of which values have been seen and how many times each one has
appeared.

The initial version of `Counter` is hard coded to only work for `u32` values.
Make the struct and its methods generic over the type of value being tracked,
that way `Counter` can track any type of value.
Comment on lines +13 to +15
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A much better way to design this exercise!


If you finish early, try using the
[`entry`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.entry)
method to halve the number of hash lookups required to implement the `count`
method.

```rust,compile_fail
{{#include exercise.rs:Counter}}
// ...
```rust,compile_fail,editable
use std::collections::HashMap;

/// Counter counts the number of times each value of type T has been seen.
struct Counter {
values: HashMap<u32, u64>,
}

impl<T> Counter<T> {
{{#include exercise.rs:new}}
todo!()
impl Counter {
/// Create a new Counter.
fn new() -> Self {
Counter {
values: HashMap::new(),
}
}

{{#include exercise.rs:count}}
todo!()
/// Count an occurrence of the given value.
fn count(&mut self, value: u32) {
if self.values.contains_key(&value) {
*self.values.get_mut(&value).unwrap() += 1;
} else {
self.values.insert(value, 1);
}
}

{{#include exercise.rs:times_seen}}
todo!()
/// Return the number of times the given value has been seen.
fn times_seen(&self, value: u32) -> u64 {
self.values.get(&value).copied().unwrap_or_default()
}
}

Expand Down
8 changes: 0 additions & 8 deletions src/std-types/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,26 @@
use std::collections::HashMap;
use std::hash::Hash;

// ANCHOR: Counter
/// Counter counts the number of times each value of type T has been seen.
struct Counter<T: Eq + Hash> {
// ANCHOR_END: Counter
values: HashMap<T, u64>,
}

impl<T: Eq + Hash> Counter<T> {
// ANCHOR: new
/// Create a new Counter.
fn new() -> Self {
// ANCHOR_END: new
Counter {
values: HashMap::new(),
}
}

// ANCHOR: count
/// Count an occurrence of the given value.
fn count(&mut self, value: T) {
// ANCHOR_END: count
*self.values.entry(value).or_default() += 1;
}

// ANCHOR: times_seen
/// Return the number of times the given value has been seen.
fn times_seen(&self, value: T) -> u64 {
// ANCHOR_END: times_seen
self.values.get(&value).copied().unwrap_or_default()
}
}
Expand Down
21 changes: 6 additions & 15 deletions src/testing/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ existing course material:
- exercises/day-1/luhn.md
---

<!-- NOTES:
Give all of the test cases, to give students a sense for how nice TDD is in Rust
-->
# Exercise: Luhn Algorithm

# Luhn Algorithm
Expand All @@ -27,22 +24,16 @@ following to validate the credit card number:

* The credit card number is valid if the sum ends with `0`.

Copy the code below to <https://play.rust-lang.org/> and implement the function.

Try to solve the problem the "simple" way first, using `for` loops and integers.
Then, revisit the solution and try to implement it with iterators.
The provided code provides a buggy implementation of the luhn algorithm, along
with two basic unit tests that confirm that most the algorithm is implemented
correctly.

Copy the code below to <https://play.rust-lang.org/> and write additional tests
to uncover bugs in the provided implementation, fixing any bugs you find.

```rust
// TODO: remove this when you're done with your implementation.
#![allow(unused_variables, dead_code)]

{{#include exercise.rs:luhn}}
unimplemented!()
}

{{#include exercise.rs:unit-tests}}

#[allow(dead_code)]
fn main() {}
}
```
Loading
Loading