Compare commits

...

8 commits

Author SHA1 Message Date
mo8it c793416495 Fix typo 2024-07-08 16:50:35 +02:00
mo8it 01343f187b Explain what a factorial is and link to wikipedia for more details 2024-07-08 16:29:43 +02:00
mo8it 69021e1497 Remove stable from book links 2024-07-08 16:00:12 +02:00
mo8it 08c408aae0 Add hint about string concatination with + 2024-07-08 15:20:56 +02:00
mo8it bf698659b0 Sync comment from exercise 2024-07-08 15:20:23 +02:00
mo8it 2d5d70693a errors3: Add a comment to prevent changing the wrong line 2024-07-08 15:05:58 +02:00
mo8it a4091ade5c iterators3: Add IntegerOverflow error variant 2024-07-08 14:40:35 +02:00
mo8it a7a881809f Check is_terminal 2024-07-08 12:53:44 +02:00
11 changed files with 52 additions and 20 deletions

View file

@ -5,5 +5,5 @@ compiler. In this section, we'll go through the most important ones.
## Further information
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
- [Data Types](https://doc.rust-lang.org/book/ch03-02-data-types.html)
- [The Slice Type](https://doc.rust-lang.org/book/ch04-03-slices.html)

View file

@ -12,6 +12,6 @@ the other useful data structure, hash maps, later.
## Further information
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/book/ch08-01-vectors.html)
- [`iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut)
- [`map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map)

View file

@ -14,7 +14,7 @@ Option types are very common in Rust code, as they have a number of uses:
## Further Information
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
- [Option Enum Format](https://doc.rust-lang.org/book/ch10-01-syntax.html#in-enum-definitions)
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
- [Option Enum Documentation](https://doc.rust-lang.org/std/option/enum.Option.html)
- [if let](https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html)

View file

@ -19,6 +19,7 @@ fn main() {
let mut tokens = 100;
let pretend_user_input = "8";
// Don't change this line.
let cost = total_cost(pretend_user_input)?;
if cost > tokens {

View file

@ -7,5 +7,5 @@ The simplest and most common use of generics is for type parameters.
## Further information
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
- [Generic Data Types](https://doc.rust-lang.org/book/ch10-01-syntax.html)
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)

View file

@ -1,12 +1,16 @@
#[derive(Debug, PartialEq, Eq)]
enum DivisionError {
// Example: 42 / 0
DivideByZero,
// Only case for `i64`: `i64::MIN / -1` because the result is `i64::MAX + 1`
IntegerOverflow,
// Example: 5 / 2 = 2.5
NotDivisible,
}
// TODO: Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
fn divide(a: i64, b: i64) -> Result<i64, DivisionError> {
todo!();
}
@ -42,6 +46,11 @@ mod tests {
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
}
#[test]
fn test_integer_overflow() {
assert_eq!(divide(i64::MIN, -1), Err(DivisionError::IntegerOverflow));
}
#[test]
fn test_not_divisible() {
assert_eq!(divide(81, 6), Err(DivisionError::NotDivisible));

View file

@ -1,5 +1,8 @@
fn factorial(num: u64) -> u64 {
// TODO: Complete this function to return the factorial of `num`.
// TODO: Complete this function to return the factorial of `num` which is
// defined as `1 * 2 * 3 * … * num`.
// https://en.wikipedia.org/wiki/Factorial
//
// Do not use:
// - early returns (using the `return` keyword explicitly)
// Try not to use:

View file

@ -309,7 +309,7 @@ In Rust, there are two ways to define a Vector.
inside the square brackets. This way is simpler when you exactly know
the initial values.
Check this chapter: https://doc.rust-lang.org/stable/book/ch08-01-vectors.html
Check this chapter: https://doc.rust-lang.org/book/ch08-01-vectors.html
of the Rust book to learn more."""
[[exercises]]
@ -378,7 +378,7 @@ dir = "06_move_semantics"
test = false
hint = """
To find the answer, you can consult the book section "References and Borrowing":
https://doc.rust-lang.org/stable/book/ch04-02-references-and-borrowing.html
https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html
The first problem is that `get_char` is taking ownership of the string. So
`data` is moved and can't be used for `string_uppercase`. `data` is moved to
@ -416,7 +416,7 @@ to its fields.
There are however some shortcuts that can be taken when instantiating structs.
Have a look in The Book to find out more:
https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax"""
https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax"""
[[exercises]]
name = "structs3"
@ -487,7 +487,7 @@ to add one character to the `if` statement, though, that will coerce the
Side note: If you're interested in learning about how this kind of reference
conversion works, you can jump ahead in the book and read this part in the
smart pointers chapter:
https://doc.rust-lang.org/stable/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods"""
https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods"""
[[exercises]]
name = "strings3"
@ -561,7 +561,7 @@ hint = """
Use the `entry()` and `or_insert()` methods of `HashMap` to achieve this.
Learn more in The Book:
https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value"""
https://doc.rust-lang.org/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value"""
[[exercises]]
name = "hashmaps3"
@ -572,7 +572,7 @@ Hint 1: Use the `entry()` and `or_insert()` (or `or_insert_with()`) methods of
exist in the table yet.
Learn more in The Book:
https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value
https://doc.rust-lang.org/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value
Hint 2: If there is already an entry for a given key, the value returned by
`entry()` can be updated based on the existing value.
@ -585,7 +585,7 @@ https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-value-based-on-
[[exercises]]
name = "quiz2"
dir = "quizzes"
hint = "No hints this time ;)"
hint = "The `+` operator can concatenate a `String` with a `&str`."
# OPTIONS
@ -739,7 +739,7 @@ name = "generics2"
dir = "14_generics"
hint = """
Related section in The Book:
https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-method-definitions"""
https://doc.rust-lang.org/book/ch10-01-syntax.html#in-method-definitions"""
# TRAITS
@ -748,7 +748,9 @@ name = "traits1"
dir = "15_traits"
hint = """
More about traits in The Book:
https://doc.rust-lang.org/book/ch10-02-traits.html"""
https://doc.rust-lang.org/book/ch10-02-traits.html
The `+` operator can concatenate a `String` with a `&str`."""
[[exercises]]
name = "traits2"
@ -869,7 +871,7 @@ We expect the method `Rectangle::new` to panic for negative values.
To handle that, you need to add a special attribute to the test function.
You can refer to the docs:
https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic"""
https://doc.rust-lang.org/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic"""
# STANDARD LIBRARY TYPES
@ -1005,7 +1007,7 @@ thread-local copy of the numbers.
This is a simple exercise if you understand the underlying concepts, but if this
is too much of a struggle, consider reading through all of Chapter 16 in The
Book:
https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html"""
https://doc.rust-lang.org/book/ch16-00-concurrency.html"""
[[exercises]]
name = "cow1"

View file

@ -1,6 +1,10 @@
#[derive(Debug, PartialEq, Eq)]
enum DivisionError {
// Example: 42 / 0
DivideByZero,
// Only case for `i64`: `i64::MIN / -1` because the result is `i64::MAX + 1`
IntegerOverflow,
// Example: 5 / 2 = 2.5
NotDivisible,
}
@ -9,6 +13,10 @@ fn divide(a: i64, b: i64) -> Result<i64, DivisionError> {
return Err(DivisionError::DivideByZero);
}
if a == i64::MIN && b == -1 {
return Err(DivisionError::IntegerOverflow);
}
if a % b != 0 {
return Err(DivisionError::NotDivisible);
}
@ -51,6 +59,11 @@ mod tests {
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
}
#[test]
fn test_integer_overflow() {
assert_eq!(divide(i64::MIN, -1), Err(DivisionError::IntegerOverflow));
}
#[test]
fn test_not_divisible() {
assert_eq!(divide(81, 6), Err(DivisionError::NotDivisible));

View file

@ -6,7 +6,7 @@
// - Append "bar" to the string a specified amount of times
//
// The exact form of this will be:
// - The input is going to be a vector of a 2-length tuple,
// - The input is going to be a vector of 2-length tuples,
// the first element is the string, the second one is the command.
// - The output element is going to be a vector of strings.

View file

@ -2,7 +2,7 @@ use anyhow::{bail, Context, Result};
use app_state::StateFileStatus;
use clap::{Parser, Subcommand};
use std::{
io::{self, BufRead, StdoutLock, Write},
io::{self, BufRead, IsTerminal, StdoutLock, Write},
path::Path,
process::exit,
};
@ -148,6 +148,10 @@ fn main() -> Result<()> {
match args.command {
None => {
if !io::stdout().is_terminal() {
bail!("Unsupported or missing terminal/TTY");
}
let notify_exercise_names = if args.manual_run {
None
} else {