My progress 15th challenge

This commit is contained in:
BraCR10 2025-07-10 01:40:15 -06:00
parent f24861957a
commit 98ef272777
62 changed files with 238 additions and 112 deletions

View File

@ -1,4 +1,4 @@
fn main() { fn main() {
// TODO: Fix the code to print "Hello world!". // TODO: Fix the code to print "Hello world!".
printline!("Hello world!"); println!("Hello world!");
} }

View File

@ -1,7 +1,7 @@
# Variables # Variables
In Rust, variables are immutable by default. In Rust, variables are immutable by default.
When a variable is immutable, once a value is bound to a name, you can't change that value. When a variable is immutable, once a value is bound to a name, you cant change that value.
You can make them mutable by adding `mut` in front of the variable name. You can make them mutable by adding `mut` in front of the variable name.
## Further information ## Further information

View File

@ -1,6 +1,6 @@
fn main() { fn main() {
// TODO: Add the missing keyword. // TODO: Add the missing keyword.
x = 5; let x = 5;
println!("x has the value {x}"); println!("x has the value {x}");
} }

View File

@ -1,6 +1,6 @@
fn main() { fn main() {
// TODO: Change the line below to fix the compiler error. // TODO: Change the line below to fix the compiler error.
let x; let x = 5;
if x == 10 { if x == 10 {
println!("x is ten!"); println!("x is ten!");

View File

@ -1,6 +1,6 @@
fn main() { fn main() {
// TODO: Change the line below to fix the compiler error. // TODO: Change the line below to fix the compiler error.
let x: i32; let x: i32=5;
println!("Number {x}"); println!("Number {x}");
} }

View File

@ -1,6 +1,6 @@
// TODO: Fix the compiler error. // TODO: Fix the compiler error.
fn main() { fn main() {
let x = 3; let mut x = 3;
println!("Number {x}"); println!("Number {x}");
x = 5; // Don't change this line x = 5; // Don't change this line

View File

@ -1,8 +1,8 @@
fn main() { fn main() {
let number = "T-H-R-E-E"; // Don't change this line let number = "T-H-R-E-E"; // Don't change this line
println!("Spell a number: {number}"); println!("Spell a number: {number}" );
// TODO: Fix the compiler error by changing the line below without renaming the variable. // TODO: Fix the compiler error by changing the line below without renaming the variable.
number = 3; let number = 5;
println!("Number plus two is: {}", number + 2); println!("Number plus two is: {}", number + 2);
} }

View File

@ -1,5 +1,5 @@
// TODO: Change the line below to fix the compiler error. // TODO: Change the line below to fix the compiler error.
const NUMBER = 3; const NUMBER:u8 = 3;
fn main() { fn main() {
println!("Number: {NUMBER}"); println!("Number: {NUMBER}");

View File

@ -1,5 +1,6 @@
// TODO: Add some function with the name `call_me` without arguments or a return value. // TODO: Add some function with the name `call_me` without arguments or a return value.
fn call_me(){}
fn main() { fn main() {
call_me(); // Don't change this line call_me(); // Don't change this line
} }

View File

@ -1,5 +1,5 @@
// TODO: Add the missing type of the argument `num` after the colon `:`. // TODO: Add the missing type of the argument `num` after the colon `:`.
fn call_me(num:) { fn call_me(num:i32) {
for i in 0..num { for i in 0..num {
println!("Ring! Call number {}", i + 1); println!("Ring! Call number {}", i + 1);
} }

View File

@ -6,5 +6,5 @@ fn call_me(num: u8) {
fn main() { fn main() {
// TODO: Fix the function call. // TODO: Fix the function call.
call_me(); call_me(8);
} }

View File

@ -8,7 +8,7 @@ fn is_even(num: i64) -> bool {
} }
// TODO: Fix the function signature. // TODO: Fix the function signature.
fn sale_price(price: i64) -> { fn sale_price(price: i64) -> i64{
if is_even(price) { if is_even(price) {
price - 10 price - 10
} else { } else {

View File

@ -1,6 +1,6 @@
// TODO: Fix the function body without changing the signature. // TODO: Fix the function body without changing the signature.
fn square(num: i32) -> i32 { fn square(num: i32) -> i32 {
num * num; num * num
} }
fn main() { fn main() {

View File

@ -4,6 +4,12 @@ fn bigger(a: i32, b: i32) -> i32 {
// Do not use: // Do not use:
// - another function call // - another function call
// - additional variables // - additional variables
if a > b {
return a;
} else if a < b {
return b;
}
a
} }
fn main() { fn main() {

View File

@ -2,8 +2,10 @@
fn picky_eater(food: &str) -> &str { fn picky_eater(food: &str) -> &str {
if food == "strawberry" { if food == "strawberry" {
"Yummy!" "Yummy!"
} else { } else if food=="potato"{
1 "I guess I can eat that."
}else {
"No thanks!"
} }
} }
@ -19,7 +21,7 @@ mod tests {
#[test] #[test]
fn yummy_food() { fn yummy_food() {
// This means that calling `picky_eater` with the argument "strawberry" should return "Yummy!". // This means that calling `picky_eater` with the argument "food" should return "Yummy!".
assert_eq!(picky_eater("strawberry"), "Yummy!"); assert_eq!(picky_eater("strawberry"), "Yummy!");
} }

View File

@ -3,11 +3,11 @@ fn animal_habitat(animal: &str) -> &str {
let identifier = if animal == "crab" { let identifier = if animal == "crab" {
1 1
} else if animal == "gopher" { } else if animal == "gopher" {
2.0 2
} else if animal == "snake" { } else if animal == "snake" {
3 3
} else { } else {
"Unknown" 4
}; };
// Don't change the expression below! // Don't change the expression below!

View File

@ -9,6 +9,8 @@ fn main() {
// TODO: Define a boolean variable with the name `is_evening` before the `if` statement below. // TODO: Define a boolean variable with the name `is_evening` before the `if` statement below.
// The value of the variable should be the negation (opposite) of `is_morning`. // The value of the variable should be the negation (opposite) of `is_morning`.
// let … // let …
let is_evening=!is_morning;
if is_evening { if is_evening {
println!("Good evening!"); println!("Good evening!");
} }

View File

@ -17,7 +17,7 @@ fn main() {
// Try a letter, try a digit (in single quotes), try a special character, try a character // Try a letter, try a digit (in single quotes), try a special character, try a character
// from a different language than your own, try an emoji 😉 // from a different language than your own, try an emoji 😉
// let your_character = ''; // let your_character = '';
let your_character = '*';
if your_character.is_alphabetic() { if your_character.is_alphabetic() {
println!("Alphabetical!"); println!("Alphabetical!");
} else if your_character.is_numeric() { } else if your_character.is_numeric() {

View File

@ -1,7 +1,7 @@
fn main() { fn main() {
// TODO: Create an array called `a` with at least 100 elements in it. // TODO: Create an array called `a` with at least 100 elements in it.
// let a = ??? // let a = ???
let a=[1;101];
if a.len() >= 100 { if a.len() >= 100 {
println!("Wow, that's a big array!"); println!("Wow, that's a big array!");
} else { } else {

View File

@ -9,7 +9,7 @@ mod tests {
let a = [1, 2, 3, 4, 5]; let a = [1, 2, 3, 4, 5];
// TODO: Get a slice called `nice_slice` out of the array `a` so that the test passes. // TODO: Get a slice called `nice_slice` out of the array `a` so that the test passes.
// let nice_slice = ??? let nice_slice = &a[1..4];
assert_eq!([2, 3, 4], nice_slice); assert_eq!([2, 3, 4], nice_slice);
} }

View File

@ -3,6 +3,6 @@ fn main() {
// TODO: Destructure the `cat` tuple in one statement so that the println works. // TODO: Destructure the `cat` tuple in one statement so that the println works.
// let /* your pattern here */ = cat; // let /* your pattern here */ = cat;
let (name,age)=cat;
println!("{name} is {age} years old"); println!("{name} is {age} years old");
} }

View File

@ -1,5 +1,6 @@
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
#[cfg(test)] #[cfg(test)]
@ -11,7 +12,8 @@ mod tests {
// TODO: Use a tuple index to access the second element of `numbers` // TODO: Use a tuple index to access the second element of `numbers`
// and assign it to a variable called `second`. // and assign it to a variable called `second`.
// let second = ???; // let second = ???;
let second = numbers.1;
assert_eq!(second, 2, "This is not the 2nd number in the tuple!"); assert_eq!(second, 2, "This is not the 2nd number in the tuple!");
} }
} }

View File

@ -3,7 +3,7 @@ fn array_and_vec() -> ([i32; 4], Vec<i32>) {
// TODO: Create a vector called `v` which contains the exact same elements as in the array `a`. // TODO: Create a vector called `v` which contains the exact same elements as in the array `a`.
// Use the vector macro. // Use the vector macro.
// let v = ???; let v: Vec<i32> = a.into_iter().collect();
(a, v) (a, v)
} }

View File

@ -1,9 +1,10 @@
fn vec_loop(input: &[i32]) -> Vec<i32> { fn vec_loop(input: &[i32]) -> Vec<i32> {
let mut output = Vec::new(); let mut output: Vec<i32> = Vec::new();
for element in input { for element in input {
// TODO: Multiply each element in the `input` slice by 2 and push it to // TODO: Multiply each element in the `input` slice by 2 and push it to
// the `output` vector. // the `output` vector.
output.push(element * 2);
} }
output output
@ -24,7 +25,7 @@ fn vec_map(input: &[i32]) -> Vec<i32> {
input input
.iter() .iter()
.map(|element| { .map(|element| {
// ??? element*2
}) })
.collect() .collect()
} }

View File

@ -1,6 +1,6 @@
// TODO: Fix the compiler error in this function. // TODO: Fix the compiler error in this function.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let vec = vec; let mut vec = vec;
vec.push(88); vec.push(88);

View File

@ -20,7 +20,7 @@ mod tests {
fn move_semantics2() { fn move_semantics2() {
let vec0 = vec![22, 44, 66]; let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0); let vec1 = fill_vec(vec0.clone());
assert_eq!(vec0, [22, 44, 66]); assert_eq!(vec0, [22, 44, 66]);
assert_eq!(vec1, [22, 44, 66, 88]); assert_eq!(vec1, [22, 44, 66, 88]);

View File

@ -1,5 +1,5 @@
// TODO: Fix the compiler error in the function without adding any new line. // TODO: Fix the compiler error in the function without adding any new line.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
vec.push(88); vec.push(88);
vec vec

View File

@ -10,8 +10,8 @@ mod tests {
fn move_semantics4() { fn move_semantics4() {
let mut x = Vec::new(); let mut x = Vec::new();
let y = &mut x; let y = &mut x;
let z = &mut x;
y.push(42); y.push(42);
let z = &mut x;
z.push(13); z.push(13);
assert_eq!(x, [42, 13]); assert_eq!(x, [42, 13]);
} }

View File

@ -4,12 +4,12 @@
// removing references (the character `&`). // removing references (the character `&`).
// Shouldn't take ownership // Shouldn't take ownership
fn get_char(data: String) -> char { fn get_char(data: &String) -> char {
data.chars().last().unwrap() data.chars().last().unwrap()
} }
// Should take ownership // Should take ownership
fn string_uppercase(mut data: &String) { fn string_uppercase(mut data: String) {
data = data.to_uppercase(); data = data.to_uppercase();
println!("{data}"); println!("{data}");
@ -18,7 +18,8 @@ fn string_uppercase(mut data: &String) {
fn main() { fn main() {
let data = "Rust is great!".to_string(); let data = "Rust is great!".to_string();
get_char(data); get_char(&data);
string_uppercase(data);
string_uppercase(&data);
} }

View File

@ -1,9 +1,16 @@
struct ColorRegularStruct { struct ColorRegularStruct {
// TODO: Add the fields that the test `regular_structs` expects. // TODO: Add the fields that the test `regular_structs` expects.
// What types should the fields have? What are the minimum and maximum values for RGB colors? // What types should the fields have? What are the minimum and maximum values for RGB colors?
red : u8,
green :u8,
blue:u8
} }
struct ColorTupleStruct(/* TODO: Add the fields that the test `tuple_structs` expects */); struct ColorTupleStruct(
u8,
u8,
u8
);
#[derive(Debug)] #[derive(Debug)]
struct UnitStruct; struct UnitStruct;
@ -19,7 +26,7 @@ mod tests {
#[test] #[test]
fn regular_structs() { fn regular_structs() {
// TODO: Instantiate a regular struct. // TODO: Instantiate a regular struct.
// let green = let green = ColorRegularStruct { red: 0, green: 255, blue: 0 };
assert_eq!(green.red, 0); assert_eq!(green.red, 0);
assert_eq!(green.green, 255); assert_eq!(green.green, 255);
@ -29,7 +36,7 @@ mod tests {
#[test] #[test]
fn tuple_structs() { fn tuple_structs() {
// TODO: Instantiate a tuple struct. // TODO: Instantiate a tuple struct.
// let green = let green = ColorTupleStruct(0,255,0);
assert_eq!(green.0, 0); assert_eq!(green.0, 0);
assert_eq!(green.1, 255); assert_eq!(green.1, 255);
@ -39,7 +46,7 @@ mod tests {
#[test] #[test]
fn unit_structs() { fn unit_structs() {
// TODO: Instantiate a unit struct. // TODO: Instantiate a unit struct.
// let unit_struct = let unit_struct = UnitStruct;
let message = format!("{unit_struct:?}s are fun!"); let message = format!("{unit_struct:?}s are fun!");
assert_eq!(message, "UnitStructs are fun!"); assert_eq!(message, "UnitStructs are fun!");

View File

@ -21,6 +21,20 @@ fn create_order_template() -> Order {
} }
} }
impl Order {
fn create_orders(name:String,year:u32,made_by_phone:bool,made_by_mobile:bool,made_by_email:bool,item_number:u32,count:u32) -> Order {
Order {
name,
year,
made_by_phone,
made_by_mobile,
made_by_email,
item_number,
count,
}
}
}
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
@ -34,7 +48,8 @@ mod tests {
let order_template = create_order_template(); let order_template = create_order_template();
// TODO: Create your own order using the update syntax and template above! // TODO: Create your own order using the update syntax and template above!
// let your_order = let your_order = Order::create_orders("Hacker in Rust".to_string(), order_template.year, order_template.made_by_phone,
order_template.made_by_mobile, order_template.made_by_email, order_template.item_number, 1);
assert_eq!(your_order.name, "Hacker in Rust"); assert_eq!(your_order.name, "Hacker in Rust");
assert_eq!(your_order.year, order_template.year); assert_eq!(your_order.year, order_template.year);

View File

@ -24,14 +24,17 @@ impl Package {
} }
// TODO: Add the correct return type to the function signature. // TODO: Add the correct return type to the function signature.
fn is_international(&self) { fn is_international(&self)->bool {
// TODO: Read the tests that use this method to find out when a package // TODO: Read the tests that use this method to find out when a package
// is considered international. // is considered international.
self.recipient_country != self.sender_country
} }
// TODO: Add the correct return type to the function signature. // TODO: Add the correct return type to the function signature.
fn get_fees(&self, cents_per_gram: u32) { fn get_fees(&self, cents_per_gram: u32)->u32 {
// TODO: Calculate the package's fees. // TODO: Calculate the package's fees.
self.weight_in_grams*cents_per_gram
} }
} }

View File

@ -1,10 +1,10 @@
# Enums # Enums
Rust allows you to define types called "enums" which enumerate possible values. Rust allows you to define types called "enums" which enumerate possible values.
Enums are a feature in many languages, but their capabilities differ in each language. Rust's enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell. Enums are a feature in many languages, but their capabilities differ in each language. Rusts enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration. Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration.
## Further information ## Further information
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html) - [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
- [Pattern syntax](https://doc.rust-lang.org/book/ch19-03-pattern-syntax.html) - [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)

View File

@ -1,6 +1,11 @@
#[derive(Debug)] #[derive(Debug)]
enum Message { enum Message {
// TODO: Define a few types of messages as used below. // TODO: Define a few types of messages as used below.
Resize
, Move
, Echo
, ChangeColor
, Quit
} }
fn main() { fn main() {

View File

@ -6,7 +6,11 @@ struct Point {
#[derive(Debug)] #[derive(Debug)]
enum Message { enum Message {
// TODO: Define the different variants used below. Resize { width: u64, height: u64 },
Move(Point),
Echo(String),
ChangeColor(u8, u8, u8),
Quit,
} }
impl Message { impl Message {

View File

@ -46,6 +46,13 @@ impl State {
fn process(&mut self, message: Message) { fn process(&mut self, message: Message) {
// TODO: Create a match expression to process the different message // TODO: Create a match expression to process the different message
// variants using the methods defined above. // variants using the methods defined above.
match message {
Message::Resize { width, height } => State::resize(self, width, height),
Message::Move(point) => State::move_position(self, point),
Message::Echo(s) => State::echo(self, s),
Message::ChangeColor(r, g, b) => State::change_color(self, r, g, b),
Message::Quit => State::quit(self),
}
} }
} }

View File

@ -1,6 +1,6 @@
// TODO: Fix the compiler error without changing the function signature. // TODO: Fix the compiler error without changing the function signature.
fn current_favorite_color() -> String { fn current_favorite_color() -> String {
"blue" "blue".to_string()
} }
fn main() { fn main() {

View File

@ -6,7 +6,7 @@ fn is_a_color_word(attempt: &str) -> bool {
fn main() { fn main() {
let word = String::from("green"); // Don't change this line. let word = String::from("green"); // Don't change this line.
if is_a_color_word(word) { if is_a_color_word(word.as_str()) {
println!("That is a color word I know!"); println!("That is a color word I know!");
} else { } else {
println!("That is not a color word I know."); println!("That is not a color word I know.");

View File

@ -1,13 +1,16 @@
fn trim_me(input: &str) -> &str { fn trim_me(input: &str) -> &str {
// TODO: Remove whitespace from both ends of a string. // TODO: Remove whitespace from both ends of a string.
input.trim()
} }
fn compose_me(input: &str) -> String { fn compose_me(input: &str) -> String {
// TODO: Add " world!" to the string! There are multiple ways to do this. // TODO: Add " world!" to the string! There are multiple ways to do this.
input.to_string() + " world!"
} }
fn replace_me(input: &str) -> String { fn replace_me(input: &str) -> String {
// TODO: Replace "cars" in the string with "balloons". // TODO: Replace "cars" in the string with "balloons".
input.replace("cars", "balloons")
} }
fn main() { fn main() {
@ -23,7 +26,6 @@ mod tests {
assert_eq!(trim_me("Hello! "), "Hello!"); assert_eq!(trim_me("Hello! "), "Hello!");
assert_eq!(trim_me(" What's up!"), "What's up!"); assert_eq!(trim_me(" What's up!"), "What's up!");
assert_eq!(trim_me(" Hola! "), "Hola!"); assert_eq!(trim_me(" Hola! "), "Hola!");
assert_eq!(trim_me("Hi!"), "Hi!");
} }
#[test] #[test]

View File

@ -13,25 +13,25 @@ fn string(arg: String) {
// Your task is to replace `placeholder(…)` with either `string_slice(…)` // Your task is to replace `placeholder(…)` with either `string_slice(…)`
// or `string(…)` depending on what you think each value is. // or `string(…)` depending on what you think each value is.
fn main() { fn main() {
placeholder("blue"); string_slice("blue");
placeholder("red".to_string()); string("red".to_string());
placeholder(String::from("hi")); string(String::from("hi"));
placeholder("rust is fun!".to_owned()); string("rust is fun!".to_owned());
placeholder("nice weather".into()); string_slice("nice weather");
placeholder(format!("Interpolation {}", "Station")); string(format!("Interpolation {}", "Station"));
// WARNING: This is byte indexing, not character indexing. // WARNING: This is byte indexing, not character indexing.
// Character indexing can be done using `s.chars().nth(INDEX)`. // Character indexing can be done using `s.chars().nth(INDEX)`.
placeholder(&String::from("abc")[0..1]); string_slice(&String::from("abc")[0..1]);
placeholder(" hello there ".trim()); string_slice(" hello there ".trim());
placeholder("Happy Monday!".replace("Mon", "Tues")); string("Happy Monday!".replace("Mon", "Tues"));
placeholder("mY sHiFt KeY iS sTiCkY".to_lowercase()); string("mY sHiFt KeY iS sTiCkY".to_lowercase());
} }

View File

@ -1,12 +1,12 @@
// TODO: Fix the compiler error about calling a private function. // TODO: Fix the compiler error about calling a private function.
mod sausage_factory { mod sausage_factory {
// Don't let anybody outside of this module see this! // Don't let anybody outside of this module see this!
fn get_secret_recipe() -> String { fn _get_secret_recipe() -> String {
String::from("Ginger") String::from("Ginger")
} }
fn make_sausage() { pub fn make_sausage() {
get_secret_recipe(); _get_secret_recipe();
println!("sausage!"); println!("sausage!");
} }
} }

View File

@ -3,8 +3,8 @@
mod delicious_snacks { mod delicious_snacks {
// TODO: Add the following two `use` statements after fixing them. // TODO: Add the following two `use` statements after fixing them.
// use self::fruits::PEAR as ???; pub use self::fruits::PEAR as fruit;
// use self::veggies::CUCUMBER as ???; pub use self::veggies::CUCUMBER as veggie;
mod fruits { mod fruits {
pub const PEAR: &str = "Pear"; pub const PEAR: &str = "Pear";
@ -18,6 +18,8 @@ mod delicious_snacks {
} }
fn main() { fn main() {
use delicious_snacks;
println!( println!(
"favorite snacks: {} and {}", "favorite snacks: {} and {}",
delicious_snacks::fruit, delicious_snacks::fruit,

View File

@ -5,7 +5,9 @@
// your scope. Bonus style points if you can do it with one line! // your scope. Bonus style points if you can do it with one line!
// use ???; // use ???;
use std::time::{SystemTime, UNIX_EPOCH};
fn main() { fn main() {
match SystemTime::now().duration_since(UNIX_EPOCH) { match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()), Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
Err(_) => panic!("SystemTime before UNIX EPOCH!"), Err(_) => panic!("SystemTime before UNIX EPOCH!"),

View File

@ -8,18 +8,26 @@ use std::collections::HashMap;
fn fruit_basket() -> HashMap<String, u32> { fn fruit_basket() -> HashMap<String, u32> {
// TODO: Declare the hash map. // TODO: Declare the hash map.
// let mut basket = let mut basket =HashMap::new();
// Two bananas are already given for you :) // Two bananas are already given for you :)
basket.insert(String::from("banana"), 2); basket.insert("banana".to_string(), 2);
// TODO: Put more fruits in your basket. // TODO: Put more fruits in your basket.
basket.insert("apples".to_string(), 2);
basket.insert("watermelon".to_string(), 2);
basket.insert("pinapple".to_string(), 2);
basket.insert("papaya".to_string(), 2);
basket basket
} }
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
let a=vec![1,2,3];
let b = a.into_iter().sum::<u64>();
print!("{b}")
} }
#[cfg(test)] #[cfg(test)]
@ -35,6 +43,6 @@ mod tests {
#[test] #[test]
fn at_least_five_fruits() { fn at_least_five_fruits() {
let basket = fruit_basket(); let basket = fruit_basket();
assert!(basket.values().sum::<u32>() >= 5); assert!(basket.into_values().sum::<u32>() >= 5);
} }
} }

View File

@ -32,6 +32,11 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
// TODO: Insert new fruits if they are not already present in the // TODO: Insert new fruits if they are not already present in the
// basket. Note that you are not allowed to put any type of fruit that's // basket. Note that you are not allowed to put any type of fruit that's
// already present! // already present!
match basket.get(&fruit) {
Some(_) => {},
None => { basket.insert(fruit, 1); },
}
} }
} }

View File

@ -6,10 +6,10 @@
// number of goals the team scored, and the total number of goals the team // number of goals the team scored, and the total number of goals the team
// conceded. // conceded.
use std::collections::HashMap; use std::{collections::HashMap};
// A structure to store the goal details of a team. // A structure to store the goal details of a team.
#[derive(Default)] #[derive(Default,Debug)]
struct TeamScores { struct TeamScores {
goals_scored: u8, goals_scored: u8,
goals_conceded: u8, goals_conceded: u8,
@ -31,6 +31,14 @@ fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
// Keep in mind that goals scored by team 1 will be the number of goals // Keep in mind that goals scored by team 1 will be the number of goals
// conceded by team 2. Similarly, goals scored by team 2 will be the // conceded by team 2. Similarly, goals scored by team 2 will be the
// number of goals conceded by team 1. // number of goals conceded by team 1.
scores.entry(team_1_name)
.and_modify(|a|
{a.goals_scored+=team_1_score ; a.goals_conceded+=team_2_score}
).or_insert(TeamScores { goals_scored: team_1_score, goals_conceded: team_2_score });
scores.entry(team_2_name)
.and_modify(|a|
{a.goals_scored+=team_2_score ; a.goals_conceded+= team_1_score})
.or_insert(TeamScores { goals_scored: team_2_score, goals_conceded: team_1_score });
} }
scores scores
@ -38,6 +46,19 @@ fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
const RESULTS: &str = "England,France,4,2
France,Italy,3,1
Poland,Spain,2,0
Germany,England,2,1
England,Spain,1,0";
let mut scores = HashMap::<&str, TeamScores>::new();
scores.entry("test").or_default();
scores.entry("test2").and_modify(|a| { a.goals_conceded += 1; });
print!("{scores:?}")
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,9 +1,15 @@
// This function returns how much ice cream there is left in the fridge. // This function returns how much icecream there is left in the fridge.
// If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00, // If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00,
// someone eats it all, so no ice cream is left (value 0). Return `None` if // someone eats it all, so no icecream is left (value 0). Return `None` if
// `hour_of_day` is higher than 23. // `hour_of_day` is higher than 23.
fn maybe_ice_cream(hour_of_day: u16) -> Option<u16> { fn maybe_icecream(hour_of_day: u16) -> Option<u16> {
// TODO: Complete the function body. // TODO: Complete the function body.
match hour_of_day {
0..22 => Some(5),
22..24=>Some(0),
_=>None,
}
} }
fn main() { fn main() {
@ -18,19 +24,19 @@ mod tests {
fn raw_value() { fn raw_value() {
// TODO: Fix this test. How do you get the value contained in the // TODO: Fix this test. How do you get the value contained in the
// Option? // Option?
let ice_creams = maybe_ice_cream(12); let icecreams = maybe_icecream(12).unwrap();
assert_eq!(ice_creams, 5); // Don't change this line. assert_eq!(icecreams, 5); // Don't change this line.
} }
#[test] #[test]
fn check_ice_cream() { fn check_icecream() {
assert_eq!(maybe_ice_cream(0), Some(5)); assert_eq!(maybe_icecream(0), Some(5));
assert_eq!(maybe_ice_cream(9), Some(5)); assert_eq!(maybe_icecream(9), Some(5));
assert_eq!(maybe_ice_cream(18), Some(5)); assert_eq!(maybe_icecream(18), Some(5));
assert_eq!(maybe_ice_cream(22), Some(0)); assert_eq!(maybe_icecream(22), Some(0));
assert_eq!(maybe_ice_cream(23), Some(0)); assert_eq!(maybe_icecream(23), Some(0));
assert_eq!(maybe_ice_cream(24), None); assert_eq!(maybe_icecream(24), None);
assert_eq!(maybe_ice_cream(25), None); assert_eq!(maybe_icecream(25), None);
} }
} }

View File

@ -10,7 +10,7 @@ mod tests {
let optional_target = Some(target); let optional_target = Some(target);
// TODO: Make this an if-let statement whose value is `Some`. // TODO: Make this an if-let statement whose value is `Some`.
word = optional_target { if let Some(word) = optional_target {
assert_eq!(word, target); assert_eq!(word, target);
} }
} }
@ -29,7 +29,7 @@ mod tests {
// TODO: Make this a while-let statement. Remember that `Vec::pop()` // TODO: Make this a while-let statement. Remember that `Vec::pop()`
// adds another layer of `Option`. You can do nested pattern matching // adds another layer of `Option`. You can do nested pattern matching
// in if-let and while-let statements. // in if-let and while-let statements.
integer = optional_integers.pop() { while let Some(Some(integer)) = optional_integers.pop() {
assert_eq!(integer, cursor); assert_eq!(integer, cursor);
cursor -= 1; cursor -= 1;
} }

View File

@ -8,8 +8,8 @@ fn main() {
let optional_point = Some(Point { x: 100, y: 200 }); let optional_point = Some(Point { x: 100, y: 200 });
// TODO: Fix the compiler error by adding something to this match statement. // TODO: Fix the compiler error by adding something to this match statement.
match optional_point { match &optional_point {
Some(p) => println!("Coordinates are {},{}", p.x, p.y), Some(p) => println!("Co-ordinates are {},{}", p.x, p.y),
_ => panic!("No match!"), _ => panic!("No match!"),
} }

View File

@ -1,8 +1,8 @@
# Error handling # Error handling
Most errors aren't serious enough to require the program to stop entirely. Most errors arent serious enough to require the program to stop entirely.
Sometimes, when a function fails, it's for a reason that you can easily interpret and respond to. Sometimes, when a function fails, its for a reason that you can easily interpret and respond to.
For example, if you try to open a file and that operation fails because the file doesn't exist, you might want to create the file instead of terminating the process. For example, if you try to open a file and that operation fails because the file doesnt exist, you might want to create the file instead of terminating the process.
## Further information ## Further information

View File

@ -4,12 +4,12 @@
// construct to `Option` that can be used to express error conditions. Change // construct to `Option` that can be used to express error conditions. Change
// the function signature and body to return `Result<String, String>` instead // the function signature and body to return `Result<String, String>` instead
// of `Option<String>`. // of `Option<String>`.
fn generate_nametag_text(name: String) -> Option<String> { fn generate_nametag_text(name: String) -> Result<String,String> {
if name.is_empty() { if name.is_empty() {
// Empty names aren't allowed // Empty names aren't allowed
None Err(format!("Empty names aren't allowed"))
} else { } else {
Some(format!("Hi! My name is {name}")) Ok(format!("Hi! My name is {name}"))
} }
} }

View File

@ -21,7 +21,8 @@ fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let cost_per_item = 5; let cost_per_item = 5;
// TODO: Handle the error case as described above. // TODO: Handle the error case as described above.
let qty = item_quantity.parse::<i32>(); let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee) Ok(qty * cost_per_item + processing_fee)
} }

View File

@ -15,7 +15,7 @@ fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
// TODO: Fix the compiler error by changing the signature and body of the // TODO: Fix the compiler error by changing the signature and body of the
// `main` function. // `main` function.
fn main() { fn main() -> Result<(), ParseIntError> {
let mut tokens = 100; let mut tokens = 100;
let pretend_user_input = "8"; let pretend_user_input = "8";
@ -28,4 +28,7 @@ fn main() {
tokens -= cost; tokens -= cost;
println!("You now have {tokens} tokens."); println!("You now have {tokens} tokens.");
} }
Ok(())
} }

View File

@ -9,8 +9,14 @@ struct PositiveNonzeroInteger(u64);
impl PositiveNonzeroInteger { impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<Self, CreationError> { fn new(value: i64) -> Result<Self, CreationError> {
// TODO: This function shouldn't always return an `Ok`. // TODO: This function shouldn't always return an `Ok`.
Ok(Self(value as u64))
match value {
x if x < 0 => Err(CreationError::Negative),
0 => Err(CreationError::Zero),
x => Ok(Self(x as u64)),
}
} }
} }

View File

@ -6,7 +6,7 @@
// //
// In short, this particular use case for boxes is for when you want to own a // In short, this particular use case for boxes is for when you want to own a
// value and you care only that it is a type which implements a particular // value and you care only that it is a type which implements a particular
// trait. To do so, the `Box` is declared as of type `Box<dyn Trait>` where // trait. To do so, The `Box` is declared as of type `Box<dyn Trait>` where
// `Trait` is the trait the compiler looks for on any value used in that // `Trait` is the trait the compiler looks for on any value used in that
// context. For this exercise, that context is the potential errors which // context. For this exercise, that context is the potential errors which
// can be returned in a `Result`. // can be returned in a `Result`.
@ -48,7 +48,7 @@ impl PositiveNonzeroInteger {
// TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we // TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we
// use to describe both errors? Is there a trait which both errors implement? // use to describe both errors? Is there a trait which both errors implement?
fn main() { fn main() -> Result<(), Box<dyn Error>> {
let pretend_user_input = "42"; let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?; let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?); println!("output={:?}", PositiveNonzeroInteger::new(x)?);

View File

@ -25,7 +25,9 @@ impl ParsePosNonzeroError {
} }
// TODO: Add another error conversion function here. // TODO: Add another error conversion function here.
// fn from_parse_int(???) -> Self { ??? } fn from_parse_int(err:ParseIntError) -> Self {
Self::ParseInt(err)
}
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -43,7 +45,7 @@ impl PositiveNonzeroInteger {
fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> { fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> {
// TODO: change this to return an appropriate error instead of panicking // TODO: change this to return an appropriate error instead of panicking
// when `parse()` returns an error. // when `parse()` returns an error.
let x: i64 = s.parse().unwrap(); let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parse_int)?;
Self::new(x).map_err(ParsePosNonzeroError::from_creation) Self::new(x).map_err(ParsePosNonzeroError::from_creation)
} }
} }

View File

@ -6,7 +6,7 @@ fn main() {
// TODO: Fix the compiler error by annotating the type of the vector // TODO: Fix the compiler error by annotating the type of the vector
// `Vec<T>`. Choose `T` as some integer type that can be created from // `Vec<T>`. Choose `T` as some integer type that can be created from
// `u8` and `i8`. // `u8` and `i8`.
let mut numbers = Vec::new(); let mut numbers: Vec<i16> = Vec::new();
// Don't change the lines below. // Don't change the lines below.
let n1: u8 = 42; let n1: u8 = 42;

View File

@ -1,12 +1,12 @@
// This powerful wrapper provides the ability to store a positive integer value. // This powerful wrapper provides the ability to store a positive integer value.
// TODO: Rewrite it using a generic so that it supports wrapping ANY type. // TODO: Rewrite it using a generic so that it supports wrapping ANY type.
struct Wrapper { struct Wrapper<T> {
value: u32, value: T,
} }
// TODO: Adapt the struct's implementation to be generic over the wrapped value. // TODO: Adapt the struct's implementation to be generic over the wrapped value.
impl Wrapper { impl<T> Wrapper<T> {
fn new(value: u32) -> Self { fn new(value: T) -> Self {
Wrapper { value } Wrapper { value }
} }
} }

View File

@ -10,6 +10,5 @@ of exercises to Rustlings, but is all about learning to write Macros.
## Further information ## Further information
- [The Rust Book - Macros](https://doc.rust-lang.org/book/ch20-05-macros.html) - [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
- [The Little Book of Rust Macros](https://veykril.github.io/tlborm/) - [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)
- [Rust by Example - macro_rules!](https://doc.rust-lang.org/rust-by-example/macros.html)

View File

@ -4,11 +4,9 @@
#[rustfmt::skip] #[rustfmt::skip]
#[allow(unused_variables, unused_assignments)] #[allow(unused_variables, unused_assignments)]
fn main() { fn main() {
let my_option: Option<&str> = None; let my_option: Option<()> = None;
// Assume that you don't know the value of `my_option`.
// In the case of `Some`, we want to print its value.
if my_option.is_none() { if my_option.is_none() {
println!("{}", my_option.unwrap()); println!("{:?}", my_option.unwrap());
} }
let my_arr = &[ let my_arr = &[

View File

@ -16,6 +16,13 @@ fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
fn calculate_price_of_apples(cant:u32)->u32{
if cant>40{
return cant;
}
cant*2
}
// Don't change the tests! // Don't change the tests!
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -27,7 +27,15 @@ mod my_module {
use super::Command; use super::Command;
// TODO: Complete the function as described above. // TODO: Complete the function as described above.
// pub fn transformer(input: ???) -> ??? { ??? } pub fn transformer(input: Vec<(String, Command)>) -> Vec<String> {
input.into_iter().map(|(s, c)| {
match c {
Command::Uppercase => s.to_uppercase(),
Command::Trim => s.trim().to_string(),
Command::Append(size) => format!("{}{}", s, "bar".repeat(size)),
}
}).collect()
}
} }
fn main() { fn main() {
@ -37,12 +45,12 @@ fn main() {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
// TODO: What do we need to import to have `transformer` in scope? // TODO: What do we need to import to have `transformer` in scope?
// use ???; use super::my_module::transformer;
use super::Command; use super::Command;
#[test] #[test]
fn it_works() { fn it_works() {
let input = vec![ let input: Vec<(String, Command)> = vec![
("hello".to_string(), Command::Uppercase), ("hello".to_string(), Command::Uppercase),
(" all roads lead to rome! ".to_string(), Command::Trim), (" all roads lead to rome! ".to_string(), Command::Trim),
("foo".to_string(), Command::Append(1)), ("foo".to_string(), Command::Append(1)),