fixed iterator1 exercise by giving the compiler less clues

This commit is contained in:
Constantin Berhard 2016-04-14 12:48:18 +02:00
parent d989bbebd0
commit 78014c0a73
2 changed files with 74 additions and 38 deletions

View file

@ -1,9 +1,10 @@
// 1. Complete the divide function // 1. Complete the divide function
// 2. Uncomment and complete the second part of the main function // 2. Uncomment and complete the second part of the main function
// For part 2 there is a minor hint around line 100 and a major hint around line 128 // For part 2 there is a minor hint around line 100 and a major hint around line 128
// There is a minor side quest in the "print_result_with_list" function // There are some final comments for when you are done around line 150
// Have fun :-) // Have fun :-)
// In production code you would not derive Debug, but implement it manually to get a better error message. // In production code you would not derive Debug, but implement it manually to get a better error message.
#[derive(Debug,PartialEq,Eq)] #[derive(Debug,PartialEq,Eq)]
enum DivisionError { enum DivisionError {
@ -19,27 +20,6 @@ struct NotDivisibleError {
// This function calculates a/b if a is divisible by b. // This function calculates a/b if a is divisible by b.
// Otherwise it returns a suitable error. // Otherwise it returns a suitable error.
fn divide(a: i32, b: i32) -> Result<i32,DivisionError> { fn divide(a: i32, b: i32) -> Result<i32,DivisionError> {
if b == 0 {
}
match a % b {
}
}
// these print functions exist, so you have to satisfy their input types in the main function
fn print_list_of_results(l: Vec<Result<i32,DivisionError>>) {
println!("{:?}", l);
}
fn print_result_with_list(r: Result<Vec<i32>,DivisionError>) {
// side quest: why is there no semicolon in this function?
match r {
Ok(v) => println!("All numbers were successfully divided: {:?}", v),
Err(e) => match e {
DivisionError::NotDivisible(nde) => println!("Failed to divide {} by {}: Not divisible!", nde.divident, nde.divisor),
DivisionError::DivideByZero => println!("Can't divide by zero"),
},
};
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -54,23 +34,28 @@ fn main() {
assert_eq!(divide(81,9),Ok(9)); assert_eq!(divide(81,9),Ok(9));
assert_eq!(divide(81,6),Err(DivisionError::NotDivisible(NotDivisibleError{divident:81,divisor:6}))); assert_eq!(divide(81,6),Err(DivisionError::NotDivisible(NotDivisibleError{divident:81,divisor:6})));
assert_eq!(divide(81,0),Err(DivisionError::DivideByZero)); assert_eq!(divide(81,0),Err(DivisionError::DivideByZero));
assert_eq!(divide(0,81),Ok(0));
println!("Your divide function seems to work! Good Job."); println!("Your divide function seems to work! Good Job.");
/* Second part of main. Uncomment to continue. /* Second part of main. Uncomment to continue.
// Don't change these numbers. It will break the assertions later in the code.
let numbers = vec![27,297,38502,81]; let numbers = vec![27,297,38502,81];
let division_results = // Do not convert the results into a Vec yet. Leave them iterable for now. let division_results = // Do not convert the results into a Vec yet. Leave them iterable for now.
let operation_mode = OperationMode::ResultWithList; let operation_mode = OperationMode::ResultWithList;
match operation_mode { match operation_mode {
OperationMode::ResultWithList => { OperationMode::ResultWithList => {
print_result_with_list(x); println!("{:?}", x);
assert_eq!(format!("{:?}",x), "Ok([1, 11, 1426, 3])");
}, },
OperationMode::ListOfResults => { OperationMode::ListOfResults => {
print_list_of_results(x); println!("{:?}", x);
assert_eq!(format!("{:?}",x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
}, },
} */ }
*/
} }
@ -90,6 +75,20 @@ fn main() {
@ -126,3 +125,40 @@ fn main() {
// Major hint: Have a look at the Iter trait and at the explanation of its collect function. Especially the part about Result is interesting. // Major hint: Have a look at the Iter trait and at the explanation of its collect function. Especially the part about Result is interesting.
// Final comments
// When you call the function `print_result_with_list` with x, you don't need any type annotations on x anymore.
// The compiler can infer its type through the function's input type.
#[allow(dead_code)]
// Don't use this function to solve the exercise
fn print_result_with_list(r: Result<Vec<i32>,DivisionError>) {
// side quest: why is there no semicolon in this function?
match r {
Ok(v) => println!("All numbers were successfully divided: {:?}", v),
Err(e) => match e {
DivisionError::NotDivisible(nde) => println!("Failed to divide {} by {}: Not divisible!", nde.divident, nde.divisor),
DivisionError::DivideByZero => println!("Can't divide by zero"),
},
};
}

View file

@ -23,10 +23,13 @@ fn divide(a: i32, b: i32) -> Result<i32,DivisionError> {
} }
} }
// these print functions exist, so you have to satisfy their input types in the main function #[allow(dead_code)]
fn print_list_of_results(l: Vec<Result<i32,DivisionError>>) { enum OperationMode {
println!("{:?}", l); ListOfResults,
ResultWithList,
} }
#[allow(dead_code)]
fn print_result_with_list(r: Result<Vec<i32>,DivisionError>) { fn print_result_with_list(r: Result<Vec<i32>,DivisionError>) {
// side quest: why is there no semicolon in this function? // side quest: why is there no semicolon in this function?
match r { match r {
@ -38,12 +41,6 @@ fn print_result_with_list(r: Result<Vec<i32>,DivisionError>) {
}; };
} }
#[allow(dead_code)]
enum OperationMode {
ListOfResults,
ResultWithList,
}
fn main() { fn main() {
// These asserts check that your `divide` function works. // These asserts check that your `divide` function works.
// In production code these would be tests // In production code these would be tests
@ -51,6 +48,7 @@ fn main() {
assert_eq!(divide(81,6),Err(DivisionError::NotDivisible(NotDivisibleError{divident:81,divisor:6}))); assert_eq!(divide(81,6),Err(DivisionError::NotDivisible(NotDivisibleError{divident:81,divisor:6})));
assert_eq!(divide(81,0),Err(DivisionError::DivideByZero)); assert_eq!(divide(81,0),Err(DivisionError::DivideByZero));
println!("Your divide function seems to work! Good Job."); println!("Your divide function seems to work! Good Job.");
// Don't change these numbers. It will break the assertions later in the code.
let numbers = vec![27,297,38502,81]; let numbers = vec![27,297,38502,81];
let numbers_iterator = numbers.into_iter(); let numbers_iterator = numbers.into_iter();
let division_results = numbers_iterator.map(|n| divide(n, 27)); let division_results = numbers_iterator.map(|n| divide(n, 27));
@ -58,11 +56,13 @@ fn main() {
match operation_mode { match operation_mode {
OperationMode::ResultWithList => { OperationMode::ResultWithList => {
let x : Result<Vec<_>,_> = division_results.collect(); let x : Result<Vec<_>,_> = division_results.collect();
print_result_with_list(x); //print_result_with_list(x);
assert_eq!(format!("{:?}",x), "Ok([1, 11, 1426, 3])");
}, },
OperationMode::ListOfResults => { OperationMode::ListOfResults => {
let x : Vec<_> = division_results.collect(); let x : Vec<_> = division_results.collect();
print_list_of_results(x); println!("{:?}", x);
assert_eq!(format!("{:?}",x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
}, },
} }
} }